8

このコードには、C# で動作しないという明確に定義された動作があります。

class Foo
{
    static List<int> to = new List<int>( from ); // from is still null
    static IEnumerable<int> from = Something();
}

注:私はすでにその方法を知っているので、そのコードを修正する方法を尋ねていません

これの正当化は何ですか?C# では、静的メンバーへの最初のアクセスを検出するためのランタイム チェックが既に行われています。これをメンバーごとに拡張して、オンデマンドで実行したり、コンパイル時にコンパイラーに順序を理解させたりしないのはなぜですか?

ところで:同じ質問(またはほぼ同じ)が非静的メンバーにも当てはまると思います。

4

4 に答える 4

12

初期化子は単なる構文糖衣です。コンパイラは、クラスをコンパイルするときにそのコードを .cctor に配置し、コードに配置されている順序で配置します。

意味がないため、チェックは実行されません。まだ初期化サイクルがある可能性があるため、とにかく機能しません。

少し前にブログに書きましたので、興味のある方はどうぞ。

于 2009-03-18T21:43:11.587 に答える
1

使用する必要があるのは静的コンストラクターだと思います。

そのようです

class Foo
{
    static List<int> to;
    static IEnumerable<int> from;

    static Foo()
    {
        from = Something();
        to = new List<int>(from);
    }
}

C# が最初のアクセスでそれを行わない理由については、何が起こっているのかを明確にする他の選択肢がある場合に、そのような複雑さの必要性がわかりません。

于 2009-03-18T21:33:01.720 に答える
1

C# はランタイム チェックを行ってクラスへの最初のアクセスを検出しますが、クラス内の静的初期化の順序を変更しません。

静的フィールドは上から下に初期化され、続いて静的コンストラクターが上から下に初期化されます。フィールドの順序を変更するか、静的コンストラクターを作成してフィールドを初期化します。

C# 仕様の変数初期化子または初期化子に関するこの記事を参照してください。

于 2009-03-18T21:34:36.083 に答える