除了其他好的答案之外,我还要添加另一个理由,为什么不将C样式的常量性放入C#中。你说:
我们将参数标记为const,以确保其状态不会在方法中更改。
如果const实际上做到了,那就太好了。const不会那样做。const是骗人的!
const不提供我可以实际使用的任何保证。假设您有一个采用const的方法。有两个代码作者:编写调用方的人和编写被调用方的人。被调用者的作者已使该方法采用const。两位作者可以假定对象是不变的吗?
没有。被调用者可以随意抛弃const并对其进行突变,因此调用者无法保证调用采用const的方法实际上不会对其进行突变。同样,被调用方不能假定对象的内容在被调用方的整个操作过程中都不会发生变化。被调用者可以在const对象的非const别名上调用某些更改方法,现在所谓的const对象已更改。
C样式const无法保证对象不会更改,因此会损坏。现在,C已经有了一个弱类型系统,如果您确实愿意,可以在其中将双精度型转换为int类型,因此对于const也具有弱类型系统也就不足为奇了。但是C#被设计为具有良好的类型系统,即当您说“此变量包含字符串”时,该类型系统实际上包含对字符串的引用(或null)。我们绝对不想将C样式的“ const”修饰符放入类型系统中,因为我们不希望类型系统成为谎言。我们希望类型系统强大,以便您可以正确地推理代码。
C中的const是一个准则 ; 它的基本意思是“您可以相信我不要试图改变这个东西”。那不应该在类型系统中 ; 在东西类型的系统应该是一个事实有关的对象,您可以推理,而不是一个指导其用途。
现在,不要误会我的意思;仅仅因为C中的const被深深地破坏并不意味着整个概念都没有用。我希望看到的是C#中“ const”注释的一种实际上正确且有用的形式,该注释可供人类和编译器使用,以帮助他们理解代码,并且运行时可用于执行自动并行化和其他高级优化。
例如,假设您可以围绕一大堆代码“画一个盒子”,然后说“我保证这一大堆代码不会对该类的任何字段进行任何更改”,这种方式可以由编译器检查。或画一个框,上面写着“此纯方法会改变对象的内部状态,但不能在框外观察到任何形式”。这样的对象不能安全地自动多线程化,但是可以被自动记录。我们可以在代码上添加各种有趣的注释,以实现丰富的优化和更深入的理解。我们可以比弱C风格的const注释做得更好。
但是,我强调这只是猜测。我们甚至没有确定的计划将这种功能集成到C#的任何假设的未来版本中,即使其中没有,我们也没有宣布一种或另一种方式。我很乐意看到这一点,将来可能需要强调多核计算,但这绝不能以任何方式解释为对C#任何特定功能或未来方向的预测或保证。
现在,如果您想要的只是局部变量上的注释,该注释是一个参数,指出“此参数的值在整个方法中都不会改变”,那么可以肯定,这很容易做到。我们可以支持将被初始化一次的“只读”局部变量和参数,以及在方法中更改的编译时错误。“ using”语句声明的变量已经是这样的局部变量了。我们可以向所有局部变量和参数添加可选注释,以使它们的行为像“使用”变量一样。它从来不是一个非常高优先级的功能,因此从未实现过。