12

私は次のクラスを持っています:

namespace Warnings
{
    public abstract class BaseWarningIntField : IWarningInnerDataField
    {
        public string PropName;

        public string HeaderCaption;

        public sealed WarningInnerDataType DataType
        {
            get { return WarningInnerDataType.Integer; }
        }
    }
}

最後のプロパティをオーバーライドできないようにしたいのはDataType、これが Integer 型の warning-detail フィールドの基本クラスであるためです。そのため、常に正しい type を返す必要がありますWarningInnerDataType.Integer

とにかく、コンパイラは私に次のエラーを与えます:

「Warnings.BaseWarningIntField.DataType」はオーバーライドではないため、封印できません

しかし、私が知る限り、私がoverride達成しようとしていることとは正反対です。

4

1 に答える 1

22

すべてのメソッドでC#、デフォルトでは非仮想です。サブクラスで非仮想メソッドをオーバーライドすることはできません。したがって、プロパティを通常どおりに残すと、サブクラスがそれをオーバーライドするのを防ぐことができます。

Sealed継承制限のためにクラス宣言で使用されるキーワードであるか、クラス階層のメンバーの仮想チェーンを停止するために使用されます。繰り返しますが、これは仮想メソッドとプロパティに関連しています。

サブクラスで「通常の」プロパティをオーバーライドしようとすると、コンパイル エラーが発生します

'WarningIntField.DataType.get': 継承されたメンバー 'BaseWarningIntField.DataType.get' は、仮想、抽象、またはオーバーライドとマークされていないため、オーバーライドできません

コメントに答えるために、私の要点を説明するためにいくつかのコード例を紹介します。派生クラスがメソッドまたはプロパティを非表示にすることを実際に制限することはできません。したがって、次の状況は合法であり、それを克服する方法はありません (これは、仮想メソッドとnewキーワードで示されるメソッドにも関連しています)

class BaseClass
{
    public string Property {get; set;}
}

class DerivedClass : BaseClass
{
    //compiler will give you a hint here, that you are hiding a base class prop
    public string Property {get; set;}
}

ローカル変数によってクラス内のフィールドを非表示にすることを制限できないのと同じように、この状況も有効です。コンパイラは、ローカル変数によってクラスフィールドを隠していることに注意するのにも役立つことに注意してください。これはreadonly const単純なstaticフィールドにも関連しています。

int field = 0; //class field
void Foo()
{
    int field = 0; //local variable
}
于 2013-03-27T15:52:48.173 に答える