为什么IEnumerable预测不可变?

时间:2015-06-02 15:15:11

标签: c# linq

假设我的Awesome类有一个属性Bazinga,它是String,默认值为“默认值”,我可以去:

    var enumerableOfAwesome = Enumerable
        .Range(1, 5)
        .Select(n => new Awesome());

    foreach (var a in enumerableOfAwesome)
        a.Bazinga = "New value";

正如您可能已经知道的那样,如果您希望在所有enumerableOfAwesome中安全地找到您的“新值”字符串,那么再次枚举Bazinga将不会让您满意。相反,将它们输出到控制台将呈现:

  

默认值
  默认值
  默认值
  默认值
  默认值

(.NET Fiddle here)

从一些延迟执行的观点来看,这一切都很好,而且之前已经讨论过这个问题,比如herehere。然而,我的问题是为什么枚举器实现不返回不可变对象;如果不能保证几个枚举的持久性,那么设置值的能力有什么用,除了让人们感到困惑之外?

也许这不是一个很好的问题,但我相信你的答案会很有启发性。

2 个答案:

答案 0 :(得分:9)

  

然而,我的问题是枚举器实现不返回不可变对象

的原因

您希望他们如何做到这一点?他们使用的是任何类型的序列 - 你期望会发生什么样的事情:

var builders = new string[] { "foo", "bar" }.Select(x => new StringBuilder(x));

?您是否期望它(无论是#34;在这种情况下是什么?)使用与StringBuilder相同的API自动创建新类型,但神奇地使其不可变?它如何检测突变?

基本上,你所要求的是不可行的 - 你可以有一个元素类型是可变的序列,所以在迭代它时你可以改变所产生的引用所指的对象。期待其他任何事都是不现实的,IMO。

答案 1 :(得分:0)

调查员并不意味着提供不变性。它们是循环遍历集合的一种方式,例如循环使用索引的标准数组。由于您可以访问底层对象,这意味着您可以更改它们。是的,C#中的不变性在集合方面更具新意义,这在枚举器中是意料之外的,无法实现。