3

私はこのようないくつかのクラスを持っています

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            A a = new C();

            a.method();
            Console.ReadLine();
        }
    }

    public class A
    {
        public virtual void method()
        {
            Console.WriteLine("METHOD FROM A");
        }
    }

    public class B : A { }

    public class C : B
    {
        public override void method()
        {
            Console.WriteLine("METHOD FROM C");
        }
    }
}

正しく動作し、「METHOD FROM C」を出力します

しかし

もし私がこのような状況にあったら

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            A a = new C();

            a.method();
            Console.ReadLine();
        }
    }

    public class A
    {
        public void method()
        {
            Console.WriteLine("METHOD FROM A");
        }
    }

    public class B : A { }

    public class C : B
    {
        public new void method()
        {
            Console.WriteLine("METHOD FROM C");
        }
    }
}

「METHOD FROM A」と表示されます。キャストを採用したり、オーバーライドでメソッド宣言を変更したりせずに、最初の例と同じ動作を取得するにはどうすればよいですか?

4

3 に答える 3

11

できません-この動作の違いは、仮想/オーバーライドを使用することの要点です。

「new」でメソッドを宣言すると、「メソッドをオーバーライドするのではなく、同じシグネチャを持つメソッドを隠していることはわかっています。ポリモーフィックな動作は必要ありません。」

同様に、「仮想」を指定せずにメソッドを宣言すると、「サブクラスがこのメソッドをオーバーライドできるようにしたくない」と言っているのです。

なぜこれをしたいのですか?仮想として宣言されていないメソッドをオーバーライドしようとしているだけですか? もしそうなら、それを回避する方法はありません - そして正当な理由があります. 作成者がポリモーフィズムを念頭に置いてクラスを設計していない場合、メソッドをオーバーライドできたとしても、簡単に壊れてしまう可能性があります。

もちろん、変数をサブクラスの型として宣言すると、次のようになります。

C c = new C();
c.method();

次に、新しく宣言されたメソッド呼び出します。

于 2010-03-02T10:20:02.890 に答える
2

ジョンが言ったように、それを避けてください。しかし

static void Main(string[] args)
    {
        A a = new C();

        (a as C).method();

        Console.ReadLine();
    }
于 2010-03-02T10:28:58.800 に答える
1

このメソッドを呼び出す動的キーワードを使用できます。

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            dynamic a = new C();

            a.method();
            Console.ReadLine();
        }
    }

    public class A
    {
        public void method()
        {
            Console.WriteLine("METHOD FROM A");
        }
    }

    public class B : A { }

    public class C : B
    {
        public new void method()
        {
            Console.WriteLine("METHOD FROM C");
        }
    }
}
于 2012-12-10T09:01:02.607 に答える