4

次の C# コードはコンパイルされません。

public class BaseType
{
    public BaseType(int bar)
    {
        // Do stuff with bar...
    }
}

public class DerivedType : BaseType
{
    private int foo;

    public DerivedType() : base(foo = 0) {}
}

エラーは、DerivedType の基本コンストラクターへの呼び出しで発生し、「静的コンテキストで非静的フィールド 'foo' にアクセスできません」というメッセージが表示されます。このエラー メッセージは何を示していますか? 「foo」は静的ではなく、クラスでもありません。これらは静的コンストラクターではありません。

4

3 に答える 3

7

base(foo = 0)クラスを実行する時点ではDerivedTypeまだ「作成」されていないため、クラスが定義するメンバーにはまだアクセスできません。

物事が起こる順序はこのようなものです

  1. ユーザーが呼び出すnew DerivedType()
  2. コードは DerivedType のbase(foo = 0)
  3. このコードは、BaseType の暗黙的なを呼び出しbase()ますObject()
  4. の任意のフィールドのメモリObjectが割り当てられ、Object()コンストラクターが最後まで実行されます。
  5. の任意のフィールドのメモリBaseTypeが割り当てられ、BaseType(int bar)コンストラクターが最後まで実行されます。
  6. の任意のフィールドのメモリDerivedTypeが割り当てられ、DerivedType()コンストラクターが最後まで実行されます。

fooしたがって、ステップ 2 で値を割り当てようとしていることがわかりますがfoo、ステップ 6 まで存在しません。

于 2013-07-10T00:51:54.177 に答える
4

問題は、コンストラクタがまだ実行されていないことです。

基本型が構築されるまで、インスタンスにアクセスすることはできません。

于 2013-07-10T00:36:46.493 に答える
3

エラーはそれfooが静的ではないことを示していますが、クラスの静的メンバーとコンストラクター自体のパラメーターのみをベースコンストラクターの呼び出しで使用できます (他の外部定数に加えて)。

あなたはおそらく意味します

public DerivedType() : base(0) {
   foo = 0;       
}

C# ドキュメントからの抜粋を非常に正確に言うと、C# 5.0 仕様のセクション 10.11.1「コンストラクター初期化子」です。

コンストラクター自体のパラメーターへのアクセスが許可されました。

インスタンス コンストラクター宣言の仮パラメーター リストによって指定されるパラメーターのスコープには、その宣言のコンストラクター初期化子が含まれます。したがって、コンストラクターの初期化子は、コンストラクターのパラメーターにアクセスできます。

ただし、インスタンスへのアクセス、したがってインスタンス フィールドへのアクセスは許可されません。

インスタンス コンストラクターの初期化子は、作成中のインスタンスにアクセスできません。したがって、コンストラクター初期化子の引数式で this を参照することはコンパイル時エラーであり、引数式が単純名を介して任意のインスタンス メンバーを参照することもコンパイル時エラーです。

于 2013-07-10T00:36:59.453 に答える