26

人々

ポリモーフィズムを理解するための多くのスレッドに出くわしました (コンパイル時と実行時の両方)。オーバーロードは実行時であり、オーバーライドはコンパイル時であるとプログラマーが主張しているリンクをいくつか見て驚きました。

ここから知りたいのは:

  1. リアルタイムの例と小さなコードを含むランタイム ポリモーフィズムと、使用すべきシナリオ。
  2. コンパイル時のポリモーフィズムとリアルタイムの例、小さなコード、およびいつ使用するか。

私は多くの理論的定義を読みましたが、それを理解することに満足していません。

また、私が感じたところでは、オーバーロードはランタイムであるべきだと考えました。なぜなら、Area を計算するメソッドがあるとします。実行時にのみ、渡したパラメーターに基づいて呼び出すオーバーロードされたメソッドを決定するからです。パラメータが 1 つの場合、Square を起動し、パラメータが 2 の場合、Rectangle を起動する必要があります。コンプライアンス時間は?(理論的には、オーバーロードはコンパイル時間であるとほとんどの人が言いますが、正しいREAL時間の例さえ与えていません...ランタイムを主張する人はほとんどいません)...

また、コードを記述してコンパイルするときに、virtual キーワードを使用し、派生クラスでそのメソッドをオーバーライドすると、コンパイル時にエラーが発生するため、オーバーライドはコンパイル時だと思います。だから、スレッドで見たのと同じように、コンパイル時間を感じます.....しかし、ほとんどのスレッドはそのランタイムを主張します:D

私は混乱しています:(この質問は私の質問1と2に追加されています.リアルタイムの例を手伝ってください..私はすでに理論的な定義を知っているので.... :(

ありがとうございました....

4

3 に答える 3

29

オーバーロードの場合、コンパイラは呼び出しているメソッドを正確に認識しているため、静的 (コンパイル時) ポリモーフィズムを使用しています。例えば:

public static class test
{
    static void Main(string[] args)
    {
        Foo();
        Foo("test");
    }

    public static void Foo()
    {
        Console.WriteLine("No message supplied");
    }

    public static void Foo(string message)
    {
        Console.WriteLine(message);
    }
}

この場合、コンパイラーは、パラメーターの数/タイプに基づいて、呼び出す Foo() メソッドを正確に認識します。

オーバーライドは、動的 (実行時) ポリモーフィズムの一例です。これは、コンパイラがコンパイル時に渡されるオブジェクトの型を必ずしも認識していないためです。ライブラリに次のクラスがあるとします。

public static class MessagePrinter
{
    public static void PrintMessage(IMessage message)
    {
        Console.WriteLine(message.GetMessage());
    }
}

public interface IMessage
{
    public string GetMessage();
}

public class XMLMessage : IMessage
{
    public string GetMessage()
    {
        return "This is an XML Message";
    }
}

public class SOAPMessage : IMessage
{
    public string GetMessage()
    {
        return "This is a SOAP Message";
    }
}

コンパイル時に、その関数の呼び出し元が XMLMessage、SOAPMessage、または別の場所で定義された別のタイプの IMessage を渡しているかどうかはわかりません。PrintMessage() 関数が呼び出されると、渡された IMessage のタイプに基づいて、実行時に使用する GetMessage() のバージョンが決定されます。

于 2012-06-06T14:17:41.770 に答える
5

Read : Polymorphism (C# Programming Guide)

Similar answer : Compile Time and run time Polymorphism

Well, there are two types of Polymorphism as stated below:

  • Static Polymorphism (Early binding)
  • Dynamic Polymorphism (Late binding)

Static Polymorphism(Early Binding):

Static Polymorphism is also know as Early Binding and Compile time Polymorphism. Method Overloading and Operator Overloading are examples of the same.

It is known as Early Binding because the compiler is aware of the functions with same name and also which overloaded function is tobe called is known at compile time.

For example:

public class Test
{
    public Test()
    {

    }

    public int add(int no1, int no2)
    {

    }

    public int add(int no1, int no2, int no3)

    {

    }
}

class Program
{
    static void Main(string[] args)
    {
        Test tst = new Test();
        int sum = tst.add(10, 20);

        // here in above statement compiler is aware at compile time that need to call function add(int no1, int no2), hence it is called early binding and it is fixed so called static binding.
    }
}

Dynamic Polymorphism(Late Binding):

public class Animal
{
    public virtual void MakeSound()
    {
        Console.WriteLine("Animal sound");
    }
}

public class Dog:Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("Dog sound");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Animal an = new Dog();
        an.MakeSound();           
        Console.ReadLine();
    }
}

As in the above code , as any other call to a virtual method, will be compiled to a callvirt IL instruction. This means that the actual method that gets called is determined at run-time (unless the JIT can optimize some special case), but the compiler checked that the method exists, it chose the most appropriate overload (if any) and it has the guarantee that the function pointer will exist at a well-defined location in the vtable of the type (even though that is an implementation detail). The process of resolving the virtual call is extremely fast (you only need to dereference a few pointers), so it doesn't make much of a difference.

于 2012-06-06T14:06:52.897 に答える
0
public class Animal {
    public virtual void MakeSound()
    {
        Console.WriteLine("Animal sound");
    } }

public class Dog:Animal {
    public override void MakeSound()
    {
        Console.WriteLine("Dog sound");
    } }

class Program {
    static void Main(string[] args)
    {
        Animal an = new Dog();
        an.MakeSound();           
        Console.ReadLine();
    } }

これは動的ポリモーフィズムです。なぜなら、子は親関数をオーバーライドしないか、それをオーバーライドする可能性があるため、実行時にどのバージョンの MakeSound が呼び出されるかが決定されるためです。 ...と呼ばれています。

于 2016-08-27T10:33:17.767 に答える