为什么常量参数不允许在C# [英] Why const parameters are not allowed in C#

查看:320
本文介绍了为什么常量参数不允许在C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这看起来很奇怪尤其是对于C ++开发人员。在C ++中,我们用来标记参数作为,以确保其状态不会方法更改常量。还有其他的C ++的具体原因也很喜欢传球 REF常量,以便通过文献传递,并确保该国将不会改变。但是,为什么我们不能在C#中标记为const的方法参数?

我为什么不能宣布我的方法是这样的:

  ....
    静态无效TestMethod1(常量MyClass的VAL)
    {}
    ....
    静态无效TestMethod2(const int的VAL)
    {}
    ....


解决方案

在除了其他很好的答案,我将添加的另一个原因,以不把C风格的常量性为C#。你说:


  

我们纪念参数作为以确保常量,它的状态不会在方法中改变。


如果常量其实这样做,那将是巨大的。 const不会做。的const是骗人的!

常量不提供,我可以实际使用的任何保证。假设你有需要一个const事情的方法。有两个code作者:写人的主叫的和写的的被叫方的人的。被叫方的作者取得了该方法需要一个const。有什么可以两位作者假设是不变的有关对象?

没有。被调用者可以自由地丢掉const和变异的对象,所以调用者没有的保证的,调用参数类型为const的方法居然会发生变异它。类似地,被叫方不能假设该对象的内容也不会在整个被叫方的动作变化;被叫方可以调用上的非const的别名的使用const对象的某些变异方法,现在所谓的const对象拥有的修改

C风格常量不保证对象将不会发生变化,并因此被破坏。现在,C已经有一个弱类型系统中,你可以做一个双重的reinter preT浇铸成一个int如果你真的想要,所以它不应该是一个惊喜,它有一个弱类型系统,相对于const的为好。但是C#设计有一个的的类型系统,类型系统,当你说这个变量包含一个字符串该变量的实际上包含一个字符串的引用的(或者为null)。我们绝对不希望把一个C风格的常量修饰符入式系统,因为我们不想要的类型系统是一个谎言的。我们想要的类型系统是的强烈的,这样就可以的理由正确的有关code。

在常量C是的指引的;这基本上意味着你可以信任我不要尝试变异这件事情。不应该在型系统的;东东在类型系统的应该是一个的实际上的有关对象,你可以推理,不是的指引的它的使用情况。

现在,不要误会我的意思;只是因为在C const的深深打破并不意味着整个概念是无用的。我很想看到一些实际的正确的和的常量的注释在C#中,注释有用的形式,人类和编译器可以用它来帮助他们了解code,并且运行时可以用来做这样的事情自动paralellization等先进的优化。

例如,想象一下,如果你能画一个框围绕code的一大块​​,并说:我的保证的这个大块头code的执行没有突变的任何领域这个类中,可能由编译器进行检查的方法。或者画一个框,说:这的纯粹的方法变异的对象的内部状态,但不以任何方式可观察外箱。这样的对象不能安全地多线程的,但自动的它可以自动memoized 的。有各种各样的,我们可以把code,这将使丰富的优化和更深入的了解有趣的注释。 我们可以做的方式都比较弱C风格的const的注释更好。

不过,我要强调,这仅仅是炒作的。我们没有任何公司计划把这种功能成C#任何假设的未来版本中,如果有,即使是其中之一,这是我们还没有公布的一种方式或其他。这是我愿意看到的,和一些东西,未来的重点放在多核计算可能需要,但是这一切都不应该是解释为是prediction或任何特定功能或未来发展方向的保证任何方式为C#。

现在,如果你想要的仅仅是在局部变量是说,一个参数一个注解这个参数的值不会在整个方法来更改,然后,当然,这将很容易做到。我们可以支持只读当地人和将被初始化一次的参数和编译时错误的方法来改变。由使用的声明中声明的变量已经是这样一个地方;我们可以添加一个可选的注释所有当地人和参数,使他们像使用的变量。这是从来没有一个很高的优先级功能,所以一直没有得到落实。

It looks strange especially for C++ developers. In C++ we used to mark parameter as const in order to be sure that its state will not be changed in method. There are also other C++ specific reasons also like passing const ref in order to pass by ref and be sure that state will not be changed. But why we can't mark as const method parameters in C# ?

Why I can't declare my method like this :

    ....  
    static void TestMethod1(const MyClass val)
    {}
    ....
    static void TestMethod2(const int val)
    {}
    ....

解决方案

In addition to the other good answers, I'll add yet another reason why to not put C-style constness into C#. You said:

we mark parameter as const in order to be sure that its state will not be changed in method.

If const actually did that, that would be great. Const doesn't do that. The const is a lie!

Const doesn't provide any guarantee that I can actually use. Suppose you have a method that takes a const thing. There are two code authors: the person writing the caller and the person writing the callee. The author of the callee has made the method take a const. What can the two authors assume is invariant about the object?

Nothing. The callee is free to cast away the const and mutate the object, so the caller has no guarantee that calling a method that takes a const actually will not mutate it. Similarly, the callee cannot assume that the contents of the object will not change throughout the action of the callee; the callee could call some mutating method on a non const alias of the const object, and now the so-called const object has changed.

C-style const provides no guarantee that the object will not change, and is therefore broken. Now, C already has a weak type system in which you can do a reinterpret cast of a double into an int if you really want to, so it should not be a surprise that it has a weak type system with respect to const as well. But C# was designed to have a good type system, a type system where when you say "this variable contains a string" that the variable actually contains a reference to a string (or null). We absolutely do not want to put a C-style "const" modifier into the type system because we don't want the type system to be a lie. We want the type system to be strong so that you can reason correctly about your code.

Const in C is a guideline; it basically means "you can trust me to not try to mutate this thing". That shouldn't be in the type system; the stuff in the type system should be a fact about the object that you can reason about, not a guideline to its usage.

Now, don't get me wrong; just because const in C is deeply broken doesn't mean that the whole concept is useless. What I would love to see is some actually correct and useful form of "const" annotation in C#, an annotation that both humans and compilers could use to help them understand the code, and that the runtime could use to do things like automatic paralellization and other advanced optimizations.

For example, imagine if you could "draw a box" around a hunk of code and say "I guarantee that this hunk of code performs no mutations to any field of this class" in a way that could be checked by the compiler. Or draw a box that says "this pure method mutates the internal state of the object but not in any way that is observable outside the box". Such an object could not be safely multi-threaded automatically but it could be automatically memoized. There are all kinds of interesting annotations we could put on code that would enable rich optimizations and deeper understanding. We can do way better than the weak C-style const annotation.

However, I emphasize that this is just speculation. We have no firm plans to put this sort of feature into any hypothetical future version of C#, if there even is one, which we have not announced one way or the other. It is something I would love to see, and something which the coming emphasis on multi-core computing might require, but none of this should be in any way construed to be a prediction or a guarantee of any particular feature or future direction for C#.

Now, if what you want is merely an annotation on the local variable that is a parameter that says "the value of this parameter doesn't change throughout the method", then, sure, that would be easily done. We could support "readonly" locals and parameters that would be initialized once, and a compile-time error to change in the method. The variable declared by the "using" statement is already such a local; we could add an optional annotation to all locals and parameters to make them act like "using" variables. It's never been a very high priority feature so it has never been implemented.

这篇关于为什么常量参数不允许在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆