views:

289

answers:

3
+4  Q: 

C# Polymorphism

Hi,
What's the difference between run-time polymorphism and compile-time polymorphism? Also, what's the difference between early binding and late binding? Examples would be highly appreciated.

+3  A: 

Polymorphism in C#

Contrast with C++

Steve Townsend
no, novicetodotnet doesn't feel like figuring out his homework.
x0n
-1 for the snark.
jfar
@jfar - point taken. Removal in progress when you sent this.
Steve Townsend
+14  A: 

Compile Time Polymorphism

Method overloading is a great example. You can have two methods with the same name but with different signatures. The compiler will choose the correct version to use at compile time.

Run-Time Polymorphism

Overriding a virtual method from a parent class in a child class is a good example. Another is a class implementing methods from an Interface. This allows you to use the more generic type in code while using the implementation specified by the child. Given the following class definitions:

public class Parent
{
    public virtual void SayHello() { Console.WriteLine("Hello World!"); }
}

public class Child : Parent
{
    public override void SayHello() { Console.WriteLine("Goodbye World!"); }
}

The following code will output "Goodbye World!":

Parent instance = new Child();
instance.SayHello();

Early Binding

Specifying the type at compile time:

SqlConnection conn = new SqlConnection();

Late Binding

The type is determined at runtime:

object conn = Activator.CreateInstance("System.Data.SqlClient.SqlConnection");
Justin Niessner
@Justin - how do .Net Generics fit into the picture here? In C++, templates express compile-time polymorphism. thx
Steve Townsend
+1  A: 

UPDATE: Please see Eric Lippert’s comments to this answer.

In C#2 all binding is early, because C#2 is a statically-typed language. A late binding language would be one in which the method binding occurs at run time. (C#4 includes a late binding feature with the introduction of dynamic.)

I am not sure what you mean by run time vs. compile time polymorphism.

The C# compiler will determine at compile time which method overload will be called. The run-time type of an instance will determine which implementation of a particular method overload will be executed. This is still considered early binding even though it happens at run time, because the selected method is constrained to be an implementation of a specific virtual method overload, and it is not possible for such a call to generate a type-related exception such as can occur with a dynamic language and late binding.

Jeffrey L Whitledge
C# 2 supports late binding at the language level in the form of *virtual dispatch*. In virtual dispatch languages the method call is *late bound* because the *exact method* called is not determined until *runtime*. The *signature* of the method is determined at compile time but the *method actually called* is not. C# 4 supports dynamic late binding: it can determine *everything* about the method (except its name) at runtime.
Eric Lippert
Re: your update: Opinions vary. Some people consider virtual dispatch to be late binding because the method called is determined at runtime. (These tend to be people with a background in C or some other mostly static binding language.) Some people consider it to be early binding because the *slot* that will contain the method pointer is determined at compile time. (These tend to be people who are used to COM programming or C++ where almost every call is virtual.) I personally try to only use "late binding" to mean "dynamic".
Eric Lippert
@Eric Lippert - OK, that makes sense. Your use of "late binding" seems similar to mine then. I have always thought of "early" and "late" to indicate, in effect, the time at which the error is detected when something goes wrong. Thanks for your comments!
Jeffrey L Whitledge
That's a great way to make the distinction. There is a lot of confusion about what the vague term "binding" even means. I agree with your proposal: to "bind" an operation is to *perform analysis that determines type information and produces either errors or a unique best type assignment*. (Where by "type information" I include members of types, like overloaded methods.)
Eric Lippert