非常に奇妙なバグと思われるものに遭遇しています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<>
が両方の構造体を考慮している方法に関連しているようです (キャッシュ メカニズムがあるのではないでしょうか?)。
何がこれを引き起こしているのか、何か考えがありますか?