C#计算不可变变量

时间:2015-03-11 10:47:10

标签: c# immutability

有没有办法告诉编译器表达式的结果从这个地方开始被认为是不可变的?

...
"const" MyClass str = b[0].x+b[1].x;
... // from here on str is an immutable object

并且const或readonly变量具有性能优势吗?


补充:@Onur: (a)应允许转让新价值; (b)不允许str的当前值,包括可以通过str访问的所有内容,例如str的任何字段以及str以任何方式引用的所有内容; (c)示例可能很困难。但我试着改写它。 str应为任何类型的数据结构(对象,集合及其任何混合)。将分配给str的对象是可变的,可以通过另一个引用进行修改。但是当分配给str时,我想确保via str不能修改对象。这背后的想法是,对象一旦被创建,将被传递给不同的线程以使用对象的数据,我想确保我不会意外地修改通过引用传递给不同线程的对象。所以我想要一些阻止我修改任何数据的引用。假设我想要某种引用,使整个对象只读。

3 个答案:

答案 0 :(得分:1)

您不能拥有readonly局部变量(例如参见Why does C# disallow readonly local variables?)。您可以在类/结构中具有只读字段。我不认为它们比普通的局部变量/普通的字段变量更快访问。

请注意,每Jon Skeet个只读字段 较慢: - )

您可以拥有const局部变量,但它只能具有可在编译时计算的值。 const变量/字段比变量更快,因为它被编译器删除了:-)(至少它对JIT更快,因为它甚至不存在于IL代码中)

此:

const int xxx = 1;
const int yyy = xxx + 1;
Console.WriteLine(yyy);

编译为

Console.WriteLine(2);

(使用ILSpy检查,即使在调试模式下)

答案 1 :(得分:0)

  1. 除了另一个常量之外,不能为const赋值。 但是,您可以定义一个私有变量,该变量可以在其类中使用您想要的任何值进行初始化,并且只显示一个只读属性及其值。

  2. 常量与immutable不同。不能更改常量的值,而可以更改指向不可变对象(如字符串)的引用的值。 如果你有一个字符串变量并且你改变它的值,那么.Net层下面发生的是字符串被销毁并且新的字符串值替换它。这就是不可变的含义。

答案 2 :(得分:0)

您可能会混淆三个不同的概念:

  • 不可变指的是对象:不可变对象是一个不能改变状态的对象,你只能创建一个基于早期对象的新对象。

  • const指的是常量。常量是一个变量,其中在编译时可以知道。例如(错误很小):

    public const double Pi = 3.14159265358979;
    public const double PiHalf = Pi/2;
    

    编译器可以简单地推断常量,并且 - 可选 - 内联时间。 Objects 通常没有常量,因为它们需要在堆上进行分配,可以对它们进行多次引用等。

  • Readonly:readonly意味着您在字段中编写一次(在构造函数级别),然后再也不会更改它们的值。

C#允许将(本地)变量标记为常量,但如前所述,这意味着必须在编译时知道该值。所以你不能 - 让我们说 - 从stdin中读取一个值,然后说变量将保持不变。但是,由于b可能是一个对象数组,因此参数不是常量,因此结果也不是。你的陈述将失败。

然而,活动分析是大多数编译器执行的过程,在许多情况下可以检测到变量不会被修改。