.NET不可变对象使用最佳实践?我应该尽可能多地使用它们吗?

Dan*_*iel 0 c# object immutability

说我有一个简单的对象,如

class Something
{
   public int SomeInt { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我已经读过使用不可变对象更快,更好地使用业务对象的方法?如果是这样,我应该努力使我的所有对象如此:

class ImmutableSomething
{
   public int SomeInt { get { return m_someInt; } }
   private int m_someInt = 0;

   public void ChangeSomeInt(int newValue)
   {
       m_someInt = newvalue;
   }
}
Run Code Online (Sandbox Code Playgroud)

你怎么看?

Ada*_*son 7

你描绘的不是一个不可改变的对象; 简单地将set代码移动到专用的setter方法不会使对象不可变.根据定义,不可变对象不能更改,因此您可以更改任何对象的属性或字段的值这一事实意味着它不是不可变的.

就"更快"或"更好"而言,不可变对象本质上不比可变对象更快或更"好"; 除了你不能改变任何价值的事实之外,没有什么特别的.


Jas*_*yon 6

正如其他人所说,你发布的内容并非一成不变.这是不可变对象的样子.的readonly关键字意味着该属性的支持字段可以被设置的唯一地方是在构造.基本上,在构造对象之后永远是它.

public class ImmutableSomething
{
    private readonly int _someInt;
    public int SomeInt
    {
        get
        {
            return _someInt;
        }
    }

    public ImmutableSomething(int i)
    {
        _someInt = i;
    }

    public ImmutableSomething Add(int i){
        return new ImmutableSomething(_someInt + i);
    }
}
Run Code Online (Sandbox Code Playgroud)

这在函数式编程中是一个大问题,因为不是谈论对象,而是谈论值.值永远不会改变,因此您知道当您将它们传递给函数或方法时,您的原始值将永远不会更改或更新.对于可变对象,您无法保证.

使用不可变对象构建的代码可以很容易地并行化,因为没有可写的共享状态.如果某个其他线程获得了您的价值并想要对其做某些事情,那么它就不能.以任何方式"改变"它会产生一个新对象,在该对象的内存中有一个全新的位置.

因此,一旦你处理了值,你就可以做一些特殊的事情,比如实习,这就是.NET用字符串做的事情.因为"Hello World"是一个值并且永远不会改变,所以对"Hello World"的引用与其他引用一样好,所以不要在内存中的一百个插槽中使用"Hello World",而是将它放在一个插槽中将所有对"Hello World"的引用设置为指向该一个槽.所以你在内存方面获得了巨大的胜利,但是你要付出性能损失,因为每当你创建一个新的字符串时,你必须检查实习池以确保它不存在.