9
public class ClassA
{
    public static readonly string processName;
} 

public class ClassB : ClassA
{
    static ClassB()
    {
        processName = "MyProcess.exe";
    }
}

上記のC#コードのコンパイル中にエラーが発生します。

エラーには、「静的読み取り専用フィールドを割り当てることはできません(静的コンストラクターまたは変数初期化子を除く)」と表示されます。

しかし、私はそれを静的コンストラクターで割り当てています。

このような静的変数の必要性は、基本クラスにはこの変数を使用するメソッドがありますが、派生クラスと基本クラスにはこの変数の異なる値が必要です。ただし、値はそれぞれのクラスのすべてのインスタンスで一定です。どこからでも変更してはならないため、読み取り専用にする必要があります。

上記のコードのエラーは何ですか?(もしあれば)見つけられないようです。エラーメッセージは役に立ちません。私はそれに従って何も悪いことをしていないので。

エラーが発生した場合、どうすればこの機能を実装できますか?簡単な回避策は、インスタンス変数にして、派生クラスで異なる値を割り当てることです。ただし、値はそれぞれのクラスのすべてのインスタンスで一定であるため、これは不要です。

4

3 に答える 3

15

ただし、間違った静的コンストラクターを割り当てています。変数を宣言する型の静的コンストラクターでのみ割り当てることができます。

同じことを行うClassCから派生した別のクラスがあるとします。つまり、読み取り専用であることが意図されている変数を上書きすることになります。ここには単一の静的変数がありますが、多くの派生クラスがあります。

1つの答えは、静的変数の使用を避け、仮想プロパティを基本クラスに配置し、各派生クラスにプロパティをオーバーライドさせて、異なる定数を返すようにすることです。

public class ClassA
{
    public virtual string ProcessName { get { return "ClassAProcess"; } }
} 

public class ClassB : ClassA
{
    public override string ProcessName { get { return "MyProcess.exe"; } }
}

基本的に、オプションは「静的」ビットを別の階層に分離することです。事実上、インスタンスではなく型にポリモーフィズムが必要なように聞こえますが、これは.NETではサポートされていません。

于 2009-09-14T10:56:42.340 に答える
5

この例では、基本クラスのフィールドが1つだけ存在し、1つのフィールドに異なる値を含めることはできません。readonlyその上、派生クラスではなく、同じクラスのフィールドのみを初期化できます。回避策は、次のようなジェネリッククラスを定義することです。

static class ProcessNames<T> {
   public static string Value { get; set; }
}

ProcessNames<DerivedClassType>.Value代わりに使用してください。明らかに、値はこの方法で公にアクセス可能になります。

ただし、各派生クラスでフィールドを個別に定義することがニーズに適合するかどうかを確認し、そうでない場合にのみ回避策に頼る必要があります。

于 2009-09-14T10:56:01.480 に答える
1

猫の皮を剥ぐ方法はたくさんあります。これがあなたがそれをすることができるもう一つの方法です。

public class ClassA
{
    public string ProcessName{ get; private set;}

    public ClassA()
    {
        ProcessName = "ClassAProcess";
    }

    public ClassA(string processName)
    {
        ProcessName = processName;
    }
}

public class ClassB : ClassA
{
    public ClassB() : base("ClassAProcess")
    {
    }
}
于 2009-09-14T11:04:01.140 に答える