对C#来说是新手。在阅读了MS编程指南和几个在线教程之后,我发现可以更改readonly引用类型对象(class)的成员( const可以应用于内置类型):
public readonly Point Origin = new Point { X = 0, Y = 0 };
Origin.X = 7; // compiles and works !!
与C++ const正确性相比,const的C#实现似乎是语言设计中的一个巨大缺陷。我漏掉了什么?还有其他方法来保证引用类型对象的恒定正确性吗?
发布于 2014-01-11 00:22:03
与C++ const正确性相比,const的C#实现似乎是语言设计中的一个巨大缺陷。
事实并非如此。事实上,事实恰恰相反。
还有其他方法来保证引用类型对象的恒定正确性吗?
在C/C++中,所谓的"const正确性“是一个错误的名词。
假设我有一个没有定义行为的程序。假设我有一个带有字段bar的对bar的引用,并通过const引用传递给方法blah。我是否有任何保证,在这个完全定义的程序中,当blah返回时,foo.bar是不变的,而不管blah是做什么的?绝对不是!假设我正在实现方法blah,并且对foo有一个const引用。我是否有任何保证,在整个blah操作过程中,bar不会被观察到改变?绝对不是!
我想要的不变条件是“这个东西不会被观察到改变”;我在C++中得到的是“您不能通过这个引用改变这个东西”。我想要得到的所谓"const正确性“所暗示的有用的不变量实际上并没有得到保证。
相比之下,在C#中,常量字段是您可以依赖的东西;不管您查看它多少次,它都将保持不变。
发布于 2014-01-10 22:00:21
根据你的标准/要求,这看起来可能是错的,也可能是不对的。
这是:
public readonly SomeClass Name = new SomeClass();
...
Name.SomeProperty = NewValue;因为readonly属性只应用于名为Name (类型为SomeClass)的字段。
它不会以任何方式传播到存储在该字段中的对象中。换句话说,您可以更改该对象中的属性和字段。
你不能做的是:
Name = new SomeClass(); // or some other reference to a SomeClass(除非你使用反射,但那是另一个故事)
现在,您可能希望const的意思是“不仅这个字段是const,而且我也只能在这个字段中存储一个const类型”,但遗憾的是,这是不可能的。
此外,您(和我)可能需要某种方式来表示“不仅这个字段是const,而且我选择在其中存储的类型也必须是不可变的”,但是不幸的是,没有(当前的)方法让编译器来验证这个位。
发布于 2014-01-10 22:02:33
我认为这只是const所代表的范式的不同而已。以下代码无法工作:
Origin = new Point();代码中除实例化以外的其他任何地方。
在Point对象的定义中,为了使X和Y都是const,您需要将它们定义为这样:
public class Point
{
const int X = 0;
const int Y = 0;
}现在,在您的示例中,X和Y都不可分配。您只会认为这是语言中的一个缺陷,因为您的C++背景。对于那些已经使用C#一段时间的人来说,这是非常自然的。
https://stackoverflow.com/questions/21055155
复制相似问题