今日、興味深いバグに遭遇しました。以下のコードは、一部のマシンではコメント行でクラッシュし、他のマシンではクラッシュしませんでした。この問題は、静的コンストラクターと静的イニシャライザーの順序付け、および継承に関連しているようです。
修正は #region のコードを別のクラスに移動することでしたが、実際に何が起こっていたのか、なぜ一部のマシンでのみ発生したように見えるのか、まだわかりません。
私はこれらの 2 つの記事を見てきました:
http://csharpindepth.com/Articles/General/Singleton.aspx
http://csharpindepth.com/Articles/General/BeforeFieldInit.aspx
これはある程度の洞察をもたらしますが、継承が物事にどのように影響するかについては触れていません。
public class CountAggregator : Aggregator
{
private static readonly CountAggregator _instance = new CountAggregator();
public static CountAggregator Instance
{
get
{
return _instance;
}
}
private CountAggregator() : base("CNT")
{
}
}
public class Aggregator
{
protected Aggregator(string id)
{
Id = id;
}
public string Id { get; private set; }
#region All Aggregators
private static readonly List<Aggregator> _allAggregators = new List<Aggregator>();
private static readonly Dictionary<string, Aggregator> _aggregatorsById = new Dictionary<string, Aggregator>();
public static IEnumerable<Aggregator> All
{
get { return _allAggregators; }
}
public static Aggregator GetAggregator(string id)
{
return _aggregatorsById[id];
}
static Aggregator()
{
_allAggregators.AddRange(new Aggregator[]
{
CountAggregator.Instance,
}
foreach (var aggregator in _allAggregators)
{
//this prints false, and the next line crashes
HtmlPage.Window.Alert((aggregator != null).ToString());
_aggregatorsById.Add(aggregator.Id, aggregator);
}
}
#endregion
}