问题描述
尤其对于C ++开发人员来说,这看起来很奇怪.在C ++中,我们曾经将参数标记为const
,以确保其状态不会在方法中更改.还有其他C ++特定的原因,例如传递const ref
以便通过ref传递,并确保不会更改状态.但是为什么我们不能在C#中将其标记为方法参数const?
It looks strange especially for C++ developers. In C++ we used to mark a parameter as const
in order to be sure that its state will not be changed in the method. There are also other C++ specific reasons, like passing const ref
in order to pass by ref and be sure that state will not be changed. But why can't we mark as method parameters const in C#?
为什么我不能像下面这样声明我的方法?
Why can't I declare my method like the following?
....
static void TestMethod1(const MyClass val)
{}
....
static void TestMethod2(const int val)
{}
....
推荐答案
除了其他好的答案之外,我还要添加另一个理由,为什么不将C样式的常量性放入C#中.你说:
In addition to the other good answers, I'll add yet another reason why to not put C-style constness into C#. You said:
如果const实际上做到了,那就太好了. const不会那样做. const是骗人的!
If const actually did that, that would be great. Const doesn't do that. The const is a lie!
Const不提供我可以实际使用的任何保证.假设您有一个采用const的方法.有两个代码作者:写 caller 的人和写 callee 的人.被调用者的作者已使该方法采用const.两位作者可以假定对象是不变的吗?
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?
什么都没有.被调用者可以随意抛弃const并对其进行变异,因此调用者没有保证的说法,调用采用const的方法实际上不会对其进行变异.同样,被调用方不能假定对象的内容在被调用方的整个操作过程中都不会发生变化;被调用者可以在const对象的非const别名上调用某种变异方法,现在所谓的const对象已发生变化 .
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样式const不能保证对象不会更改,因此会损坏.现在,C已经有了一个弱类型系统,如果您确实愿意,可以在其中将双精度型转换为int类型,因此对于const也具有弱类型系统也就不足为奇了.但是C#被设计为具有 good 类型系统,即当您说此变量包含字符串"时,该类型系统实际上是变量包含对字符串的引用(或null).我们绝对不希望将C样式的"const"修饰符放入类型系统中,因为我们不希望类型系统成为谎言.我们希望类型系统为 strong ,以便您可以正确理解您的代码.
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.
C语言中的常量是准则;它的基本意思是您可以相信我不要试图改变这个东西".那不应该在 type系统中; 类型系统中的内容应该是关于您可以推理的对象的事实",而不是有关其用法的准则.
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.
现在,不要误会我的意思;仅仅因为C中的const被深深地破坏并不意味着整个概念是无用的.我希望看到的是C#中"const"注释的一些实际上正确和有用的形式,人类和编译器都可以使用该注释来帮助他们理解代码,并且运行时可用于执行自动并行化和其他高级优化等操作.
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.
例如,想象一下您是否可以在一大堆代码周围画一个盒子",并说我 该大块代码不会对该类的任何字段进行任何改动"可以由编译器检查.或绘制一个框,上面写着此 pure 方法会改变对象的内部状态,但不能在框外观察到任何形式".这样的对象不能安全地自动进行多线程处理,但是可以自动将其记忆化.我们可以在代码上添加各种有趣的注释,以实现丰富的优化和更深入的理解. 我们可以比弱C风格的const注释做得更好.
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.
但是,我强调这只是推测.我们甚至没有确定的计划将这种功能添加到任何假设的C#未来版本中,即使其中没有,我们也没有以任何一种方式宣布.我很乐意看到这一点,将来可能需要强调多核计算,但这绝不能以任何方式解释为对C#任何特定功能或未来方向的预测或保证.
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#.
现在,如果您想要的只是局部变量上的注释,该注释是一个表明该参数的值在整个方法中都不会改变"的参数,那么可以肯定,这很容易做到.我们可以支持将被初始化一次的只读"局部变量和参数,以及在方法中更改的编译时错误.由"using"语句声明的变量已经是本地变量了.我们可以向所有局部变量和参数添加可选注释,以使它们的行为像使用"变量一样.它从来都不是优先级很高的功能,因此从未实现过.
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#中不允许使用const参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!