6

コード :

public class A {
    public const int beingSupportedRate = 0;
}

 public partial class B : A {
    public const int beingSupportedRate = 1;

}

パフォーマンスのために const int と同じくらい明示的にしたい。class A変数の前に virtual を置くと、beingSupportedRate次のコンパイラ エラーが発生します。

The modifier 'virtual' is not valid for this item

4

5 に答える 5

13

new継承されたメンバーを明示的に非表示にするには、キーワードを使用する必要があります。

public class A
{
    public const int beingSupportedRate = 0;
}

public class B : A
{
    public new const int beingSupportedRate = 1;
}

インスタンスから定数メンバーにアクセスできないことに注意してください。

Console.WriteLine(A.beingSupportedRate);
Console.WriteLine(B.beingSupportedRate);

出力:

0
1

このソリューションを使用する際に考慮すべき問題がいくつかあります。たとえば、次のコンソール プログラムを考えてみましょう。

class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        B b = new B();
        C c = new C();

        a.GetBeingSupportRate();
        b.GetBeingSupportRate();
        c.GetBeingSupportRate();

        Console.Read();
    }

    public class A
    {
        public const int beingSupportedRate = 0;
        public void GetBeingSupportRate()
        {
            Console.WriteLine(beingSupportedRate);
        }
    }

    public class B : A
    {
        public new const int beingSupportedRate = 1;

    }

    public class C : B
    {

    }
}

継承されたメソッドは A の定数値を使用するため、これは 3 つのクラス インスタンスすべてに対して出力0されます。これは、定数を参照するすべてのメソッドをオーバーライドする必要があることを意味します。

推奨されるアプローチは、実装する必要があるプロパティを持つインターフェイスを使用し、この目的で定数を使用しないことです。

于 2013-03-01T13:09:54.453 に答える
8

フィールド (定数を含む) を仮想にすることはできません。それは定数であることとは何の関係もありません...それはフィールドが機能する方法にすぎません...ただし、定数が暗黙的に静的であるという事実は、いわば実現可能性をさらに低くします。

ポリモーフィックな動作が必要な場合、プロパティ、メソッド、またはイベントであるインスタンス メンバーを介する必要があります。

余談ですが、 「パフォーマンス上の理由からそれが欲しい」という正当化は、偽のマイクロ最適化であると強く疑っています。constこれをどのように使用しているのかさえ明らかではありませんが、非定数として試して、遅すぎることを証明したとは思えません。

于 2013-03-01T13:05:48.730 に答える
5

実際、あなたはオブジェクト指向プログラミングにおけるポリモーフィズムのポイントを誤解していると思います。

定数、フィールド、および変数は単なるストレージです (まあ、参照ですが、私は概念的な観点から話しています)。

ポリモーフィズムとは、何かの動作を変更することです。定数をオーバーライドすることは、動作を変更することではなく、その値を変更することです

別のポイントは、定数はstaticであるため、インスタンスに属していませんが、不変の単一の値がありAppDomain、アプリケーションのライフサイクルの間存続します。

上記のステートメントで、なぜインスタンス メンバーのような定数をオーバーライドしたいのでしょうか? 次の状況を想像できますか?

public class A 
{
      public virtual const int Some = 1;
}

public class B : A
{
      public override const int Some = 2;
}

public class C : A
{
     // No override here!
}

int valueOfSomeConstant = C.Some;

所有!定数が静的である場合、定数をオーバーライドしないC.Some場合2でも同じです!C

あなたの質問からの引用:

パフォーマンスのために const int と同じくらい明示的にしたい。[...]

これには答えしかありません。時期尚早の最適化は、ソフトウェア開発の悪魔です。

Jon Skeetが言ったように、これはあなたの問題の中で最も少ないものになるでしょう.

于 2013-03-01T13:28:29.297 に答える
5

定数はオーバーライドできません。定数です。

この値を拡張によって変更可能にしたい場合は、実装またはオーバーライドする要素など、コンテキストごとに変更されるという性質を持つ、定数の少ないものを使用する必要があります。abstractvirtual

于 2013-03-01T13:05:32.363 に答える
3

Uはこれを行うことができます:

public class A 
{
    public virtual Int32 beingSupportedRate
    { 
        get { return 0; }
    }
}

public class B : A
{
    public override Int32 beingSupportedRate 
    {
        get { return 1; }
    }
}
于 2013-03-01T13:15:16.800 に答える