C#中的不可变类型和属性

Yod*_*dha 24 c# types immutability

C#中的不可变类型和不可变属性是什么意思?你能举一个简单的例子吗?

fre*_*tje 30

不可变类型是一种只能在初始化时设置其属性的类型.创建对象后,就不能再进行任何更改.不可变属性只是一个只读属性.

在以下示例中,ImmutableType是具有一个属性的不可变类型Test.Test是一个只读属性.它只能在施工时设置.

class ImmutableType
{
    private readonly string _test;
    public string Test
    {
        get { return _test; }
    }

    public ImmutableType(string test)
    {
        _test = test;
    }
}
Run Code Online (Sandbox Code Playgroud)

另请参阅:Wikipedia文章以及有关该主题的一些Stack Overflow问题.

  • 您可以通过使用readonly前缀_test来强制执行针对未来类更改的不变性.遗憾的是,C#中没有不可变的自动实现属性. (4认同)
  • 当您的属性是引用类型时,这会变得有点棘手.那么,不可变的定义可以被解释为*reference*是不可变的_or_*对象图*是不可变的(取决于你的需要,但通常是后者 - 参见Wiki文章). (3认同)
  • 注意:Sam的评论不再合适.从C#6开始,您可以使用`{get;}来获得不可变的自动实现属性.}` (2认同)

Stu*_*tLC 6

除了上述@fretje的答案之外,在C#6和更高版本中,现在还实现了仅吸气剂的自动属性,该属性允许不可变的自动属性,而无需其他显式的private readonly后备字段。等效代码将缩写为:

class ImmutableType
{
    public string Test
    {
        get; // No Set at all, not even a private set.
    }

    public ImmutableType(string test)
    {
        Test = test; // The compiler understands this and initializes the backing field
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意private set(在C#的早期版本中使用自动属性可以获得最接近不变性的信息)仅提供了对同一类中的属性更改的受限封装,因此并不是真正的不变性:

public string Test
{
    get;
    private set;  // Not immutable, since this is still mutable from within the class
}
Run Code Online (Sandbox Code Playgroud)

关于不变性的更多信息

正如其他人所说,an immutable Property是一经设置便无法更改的属性。通常在构造函数中设置“ only value”。

An immutable Type是所有(外部可见的)属性和字段都不可变的类型,例如,最初计划用于C#7的“记录”类型(希望现在是8)将是不可变的类型。不可变类型的其他示例还有Tuples和所有匿名类

不可变字段应使用readonlyC#中的关键字进行限定-编译器会强制执行此操作,以确保没有其他代码尝试在构造函数之外更改字段。

只要有可能,将字段,变量和属性的不可变性视为一种良好做法,因为这会大大减少bug的表面积(因为字段表示对象的状态,防止更改字段会减少状态数)。

不变性的好处在多线程程序中尤其重要,在多线程程序中,两个或多个线程同时访问同一对象。由于多个并发读取线程可以安全地访问字段或属性的值,因此程序员无需担心与其他线程更改字段有关的线程安全问题。

当处理由多个组合对象组成的复杂对象时,不变性的一个常见缺点是,整个图需要“一次性完成”,这可能导致代码混乱。此处的常见解决方案是将Builder模式用作支架,从而允许逐步构建瞬态可变的表示形式,然后在最终.Build()步骤中获得最终的不可变对象。