web-dev-qa-db-ja.com

C#での派生クラスの定数のオーバーライド

C#では、派生クラスで定数をオーバーライドできますか?いくつかの定数値がすべて同じバーであるクラスのグループがあるので、すべてのメソッドを定義し、派生クラスで関連する定数を設定するだけの基本クラスを作成したいと思います。これは可能ですか?

複数のクラスの型安全性を追加したいので、これらの値を各オブジェクトのコンストラクターに渡すだけではなく(定数が異なる2つのオブジェクトが相互作用することは意味がないため)。

40
Frankly

オーバーライドしたい場合は、定数ではありません;)。仮想読み取り専用プロパティ(または保護されたセッター)を試します。

読み取り専用プロパティ:

public class MyClass {
    public virtual string MyConst { get { return "SOMETHING"; } }
}
...
public class MyDerived : MyClass {
    public override string MyConst { get { return "SOMETHINGELSE"; } }
}

保護されたセッター:

public class MyClass {
    public string MyConst { get; protected set; }

    public MyClass() {
        MyConst = "SOMETHING";
    }
}

public class MyDerived : MyClass {
    public MyDerived() {
        MyConst = "SOMETHING ELSE";
    }
}
56
Tracker1

残念ながら、定数は仮想メンバーではないため、オーバーライドできません。コード内の定数識別子は、コンパイル時にコンパイラによってリテラル値に置き換えられます。

私はあなたがしたいことのために抽象または仮想プロパティを使用しようとすることをお勧めします。これらは仮想であり、そのため(抽象プロパティの場合は)派生型でオーバーライドできます。

31
Andrew Hare

constでマークされた定数は、コンパイル時にコンパイラーによって置き換えられるため、オーバーライドできません。

しかし、定数値に割り当てられた通常の静的フィールドはできます。私は今そのようなケースを抱えています:

class Columns
{
    public static int MaxFactCell = 7;
}

class Columns2 : Columns
{
    static Columns2()
    {
        MaxFactCell = 13;
    }
}

代わりに、派生クラスのMaxFactCellフィールドを再定義しただけでは、ポリモーフィズムが機能しません。Columns2Columnsとして使用するコードでは、オーバーライド値が表示されません。

フィールドへの書き込み(読み取りではなく)アクセスを制限する必要がある場合は、readonlyを使用すると、Columns2での再定義が禁止されます。代わりにそれをプロパティにしてください、それは少し多くのコードです:

class Columns
{
    static Columns()
    {
        MaxFactCell = 7;
    }            
    public static int MaxFactCell { get; protected set; }
}

class Columns2 : Columns
{
    static Columns2()
    {
        MaxFactCell = 13;
    }
}
4
ivan_pozdeev

新しい定数newを宣言することにより、派生クラスで継承された定数を非表示にすることができます。ただし、これが良い方法かどうかはわかりません。

class A
{
    protected const int MyConst = 1;
}

class B : A
{
    new private const int MyConst = 2;
}
3
Jiří Skála

dten + Tracker1の回答を回避するが、c#6用に更新

public class MyClass {
    public virtual string MyConst =>"SOMETHING";
}
...
public class MyDerived : MyClass {
    public override string MyConst  =>"SOMETHING ELSE";
}
1
Marc Ziss

派生クラスに定数の値を強制することができます(まあ、読み取り専用プロパティ)

  • 読み取り専用プロパティを含むインターフェースを作成します。
  • そのインターフェイスを基本クラスに配置します。

例:

   public interface IHasConstant
   {
        string MyConst { get; }
   }
0
user1023602