Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#计算不可变变量_C#_Immutability - Fatal编程技术网

C#计算不可变变量

C#计算不可变变量,c#,immutability,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) 举例可能很难。但我试着换个说法。s

有没有办法告诉编译器,表达式的结果从此处起将被视为不可变的

...
"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时,我想确保通过str不可能修改对象。其背后的思想是,一旦创建了对象,它将被传递给不同的线程以处理对象的数据,我希望确保不会意外地修改通过引用传递给不同线程的对象。因此,我需要某种引用,以防止我修改任何数据。假设我需要某种类型的引用,使整个对象成为只读。

不能使用
readonly
局部变量(参见示例)。类/结构中可以有一个只读字段。我认为它们的访问速度并不比普通的局部变量/普通的字段变量快

请注意,每个只读字段的速度较慢:-)

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

这:

编译为

Console.WriteLine(2);
(使用ILSpy检查,即使在调试模式下)

  • 除了另一个常量外,不能为常量赋值。 但是,您可以定义一个私有变量,该变量可以在它的类中使用您想要的任何值进行初始化,并且只需使用它的值公开一个只读属性

  • 常量与不可变的不同。常量的值不能更改,而指向不可变对象(如字符串)的引用的值可以更改。 当您有一个字符串变量并更改其值时,.Net层下面发生的情况是,该字符串被销毁,新的字符串值将替换它。这就是不变的含义


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

    • Immutable指的是对象:不可变对象是一个不能更改状态的对象,例如,您只能基于以前的对象创建一个新对象

    • const
      指常数。常量是一个变量,其值在编译时已知。例如(误差较小):

      编译器可以简单地对常量和内联时间进行推理(可选)。对象通常没有常量,因为它们需要在堆上分配,可以有多个对它们的引用,等等

    • :readonly表示您对字段写入一次(在构造函数级别),然后不再更改其值

    C#允许将(局部)变量标记为常量,但如前所述,这意味着该值必须在编译时已知。所以你不能——比方说——从stdin中读入一个值,然后说变量将保持不变。然而,由于
    b
    很可能是一个对象数组,因此参数不是常量,因此结果也不是常量。因此,你的陈述将失败


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

    看起来您混淆了常量和不变性。字符串在C#中已经是不可变的。const或readonly对性能没有什么好处,它们主要是为了帮助可维护性。我认为不应该在运行时更改(初始化)const变量。我将字符串更改为MyClass。我没有想到字符串默认为只读。你能澄清一下(a)str是否不应该被分配一个新值;(b) str的当前值不可修改或(c)其他值;也许一个例子可以帮助说明什么应该(不应该)被允许
    Console.WriteLine(2);
    
    public const double Pi = 3.14159265358979;
    public const double PiHalf = Pi/2;