ImmutableArray<>行为与Array<>不同用于嵌套选择索引

时间:2013-09-10 11:01:12

标签: c# linq immutability base-class-library

我在ImmutableArray<>遇到了一个非常奇怪的错误(使用BCL Immutable集合v1.0.12.0,运行时.NET 4.5):

我在同一名称空间下的同一源文件中完全具有以下两个相同的结构:

public struct WeightedComponent {
    public readonly IComponent Component;
    public readonly decimal Weight;

    public WeightedComponent(IComponent component, decimal weight) {
        this.Component = component;
        this.Weight = weight;
    }
}

public struct WeightedComponent2 {
    public readonly IComponent Component;
    public readonly decimal Weight;

    public WeightedComponent2(IComponent component, decimal weight) {
        this.Component = component;
        this.Weight = weight;
    }
}

以下内容将抛出异常:

var elements1 = new[] { 1, 2, 3 }.Select(wc => new WeightedComponent(null, 0)).ToImmutableArray();
var foo = elements1.Select((e1, i1) => elements1.Select((e2, i2) => 0).ToArray()).ToArray();
if (foo.Length != 3) throw new Exception("Error: " + foo.Length); //Error: 1

var elements2 = new[] { 1, 2, 3 }.Select(wc => new WeightedComponent2(null, 0)).ToImmutableArray();
var foo2 = elements2.Select((e1, i1) => elements2.Select((e2, i2) => 0).ToArray()).ToArray();
if (foo2.Length != 3) throw new Exception("Error: " + foo.Length);

如果我将第1行中的elements1投影到ToArray()而不是ToImmutableArray(),那么一切正常。

两个结构之间的唯一区别是之前代码广泛使用WeightedComponent,而之前从未使用WeightedComponent2(这就是重现错误可能不明显的原因)。

在同一个表达式中对elements1两次迭代似乎与该问题有关,就好像我将其删除Select工作正常,但elements2没有这样的问题。 它似乎与ImmutableArray<>背后的代码考虑两种结构的方式有关(可能有一种缓存机制?)

你知道造成这种情况的原因是什么吗?

1 个答案:

答案 0 :(得分:4)

这是由于ImmutableArray<T>枚举器中的错误,在您第一次枚举该集合的空实例时触发。 NuGet包的未来版本将修复该问题。与此同时,我强烈建议您避免使用ImmutableArray<T>