ImmutableArray<> 的行为与 Array<> 对于带索引的嵌套选择

本文关键字:于带 索引 选择 嵌套 ImmutableArray Array | 更新日期: 2023-09-27 18:30:50

>我在ImmutableArray<>中遇到了一个似乎非常奇怪的错误(使用 BCL 不可变集合 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);

如果我将 element1 投影到第一行而不是ToImmutableArray() ToArray()中,一切正常。

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

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

你知道是什么原因造成的吗?

ImmutableArray<> 的行为与 Array<> 对于带索引的嵌套选择

这是

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