5

アプリケーションでは、コンパイル時の型ではなく実行時の型に基づいてメソッドを呼び出す .NET が必要です。

簡単な例:

    class A { }

    class B : A { }

    static void Main(string[] args)
    {
        A b = new B();
        Print(b);
    }

    static void Print(A a)
    {
        Console.WriteLine("Called from A");
    }

    static void Print(B b)
    {
        Console.WriteLine("Called from B");
    }

上記のコードは実際にはを出力しますCalled from Aが、必要なのはCalled from B.

これは期待どおりに機能します。

static void Print(A a)
{
    var b = a as B;
    if (b != null)
       return Print(b);
    else
       Console.WriteLine("Called from A");
}

しかし、保守性のために、それは望ましくありません。

この質問は次の質問に似ていると思います:オブジェクトのランタイム タイプに基づいてこのメソッドが選択されないのはなぜですか? 、ただし Java ではなく .NET 用です。

4

5 に答える 5

10

.NET 4以降を使用している場合の最も簡単なアプローチは、動的型付けを使用することです。

dynamic b = new B();
Print(b);

タイプの値を使用するほとんどすべての式dynamicは動的に呼び出され、「ミニC#コンパイラ」は、コンパイル時と同じルールを実行時に適用しますが、これらの動的な値の実際の実行時タイプを使用します。 。(ただし、コンパイル時に型が静的に認識されている式は、それらの型を持っていると見なされます。ただし、過負荷の解決に関するすべてが動的になるわけではありません。)

.NET 4を使用していない場合は、やや難しくなります。リフレクションを使用するか、オプションをハードコーディングすることができますが、どちらも楽しいことではありません。

于 2013-01-25T14:07:22.123 に答える
5

dynamic次のタイプを利用できます。

A b = new B();
dynamic tmp = b;
Print(tmp); // Prints "Called from B"

ただし、これには、一致するメソッドがない場合にコンパイルエラーではなくランタイム例外が生成されるという欠点があることに注意してください。

于 2013-01-25T14:06:40.110 に答える
4

OOP のオーバーライドを使用します。

例:

class A { 

    public virtual void Print() { 
          Console.WriteLine("Called from A");
    }      
}

class B : A { 
    public override void Print() { 
          Console.WriteLine("Called from B");
    }  
 }

次のように使用します。

    A b = new B();
    Print(b);


    static void Print(A a)
    {
       a.Print(); //will run B's method
    }

単純なオーバーライドの概念を使用するため、ランタイムタイプ メソッドが実行されます。

于 2013-01-25T14:08:52.683 に答える
0

これは、ポリモーフィズムが機能する方法ではありません。代わりに、次のようなことを検討する必要があります。

class A
{
    virtual string GetString()
    {
        return "Called from A";
    }
}

class B : A
{
    override string GetString()
    {
        return "Called from B";
    }
}

static void Main(string[] args)
{
    A b = new B();
    Print(b);
}

static void Print(A a)
{
    Console.WriteLine(a.GetString());
}
于 2013-01-25T14:13:33.070 に答える
0

これを試して:

class A
{
    public virtual string Print()
    {
        return "Called from A";
    }
}

class B : A
{
    public override string  Print()
    {
        return "Called from B";
    }
}

そして他の場所でそれをテストします

A b = new B();
MessageBox.Show(b.Print()); //called from B
于 2013-01-25T14:14:09.523 に答える