6

非常に奇妙なバグと思われるものに遭遇していますImmutableArray<>(BCL 不変コレクション v1.0.12.0、ランタイム .NET 4.5 を使用):

同じ名前空間の同じソース ファイルに、次の 2 つの同一の構造体があります。

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);

ToArray()の代わりに最初の行にelements1 を投影するとToImmutableArray()、すべて正常に動作します。

2 つの構造体の唯一の違いは、WeightedComponent以前はコードで広く使用されていたのに対し、以前は使用されていWeightedComponent2なかったということです (これが、バグを再現することが明らかでない理由です)。

同じ式で 2 回反復elements1すると、問題に関連しているように見えます。削除した場合はSelect正常に動作しますが、elements2. これは、コード ビハインドImmutableArray<>が両方の構造体を考慮している方法に関連しているようです (キャッシュ メカニズムがあるのではないでしょうか?)。

何がこれを引き起こしているのか、何か考えがありますか?

4

1 に答える 1

5

これはImmutableArray<T>、コレクションの空のインスタンスを初めて列挙したときにトリガーされる、列挙子のバグによるものです。NuGet パッケージの将来のバージョンでは、この問題が修正される予定です。それまでの間、 の使用を避けることを強くお勧めしますImmutableArray<T>

于 2013-09-11T03:36:13.697 に答える