我喜欢不变性概念,但有时我想知道,当一个应用程序不是平行的时候,应该避免让事情变得不可变吗?

当应用程序不是多线程的时,您不会受到共享状态问题的困扰,对吧?

或者不可变性是像OOP这样的概念,你要么一直使用?排除基于使用/性能等因素不应该是不可变的情况

在为自己编写应用程序时,我遇到了这个问题,这个问题适度大(可能像1-2k行)。

有帮助吗?

解决方案

我喜欢不变性,因为这意味着我不必相信其他人的代码,不要乱用我希望保持不变的对象。

当您将一个对象传递给另一个组件(例如List<T>)时,您将受到该组件的作用。将集合作为属性返回时,这一点尤其重要。

public class Foo { 
  private List<Bar> _barList;
  public ICollection<Bar> BarList { get return _barList; } 
}

没有什么可以阻止这个类的消费者清除我下面的收藏品。即使将返回类型切换为IEnumerable<Bar>也不完全安全。没有什么可以阻止某些编写错误的代码将其转换回<=>并调用.Clear()。

但是,如果我真的希望该集合保持一致,我可以将其重写为followis

public class Foo {
  private ImmutableCollection<Bar> _barList;
  public ImmutableCollection<Bar> BarList { get { return _barList; } }
}

现在我不必信任其他代码错误地使用我的类。他们不能弄乱它。

其他提示

我喜欢不可变性的优势,只需要在创建对象时验证它一次。实际上这是一个巨大的奖金。

不变性的一个主要好处是不需要跟踪不可变对象的所有权。只要有人需要它们,它们就存在,然后当它们不再需要时就消失在虚无之中。虽然在许多情况下使用垃圾收集器意味着没有必要编写任何明确的代码来处理可变对象的所有权(最大的例外是那些实现IDisposable的对象),在许多情况下,编写正确的代码对象非常困难具有可变状态的,没有一个明确定义的<!>“所有者<!>”;关于谁拥有可变对象状态的困惑可能是一个非常频繁的错误来源;当使用不可变对象(除了少数实现List<T>)之外,通常可以忽略所有权问题。

另一个需要考虑的问题是,推断对语义不可变对象的可变引用或对可变对象的不可变引用要比推断对可变对象的可变引用要容易得多。如果有一个可变对象的可变引用,通常不清楚更新状态的正确方法是直接改变对象,还是将其状态复制到新对象,改变它,并更新引用。在某些情况下,会出现需要每种类型操作的情况(与<=>一样,有时会用较大的数组替换数组,但通常会在适当位置进行更新),但这种方法只有在类型保持独占的情况下才有效控制有问题的可变对象。对可变类型进行不可变引用通常更有帮助(在这种情况下,代码可能会通过只读包装器将引用公开给需要<!>“实时视图<!>”的其他对象;它的状态)或者对一个不可变的对象有一个可变的引用,或者至少在引用的生命周期内永远不会发生变异。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top