What's going on with this method overloading?

I have a question about method overloading in C#. I have a parent class and a child class.

class Parent
{
    public virtual string GetMyClassName()
    {
        return "I'm a Parent";
    }
}

class Child : Parent
{
    public override string GetMyClassName()
    {
        return "I'm a Child";
    }
}

I have two static methods declared outside of those two classes that act on objects of either type:

static string MyClassName(Parent parent)
{
    return "That's a Parent";
}

static string MyClassName(Child child)
{
    return "That's a Child";
}

When I test out how these methods are all called, I get what I think is a strange result:

Parent p = new Child();
var str1 = MyClassName(p); // = "That's a Parent"
var str2 = p.GetMyClassName(); // = "I'm a Child"

Why does str1 get set to "That's a Parent"? I am probably misunderstanding method overloading in C#. Is there a way to force the code use the Child call (setting str1 to "That's a Child")?

Jon Skeet
people
quotationmark

Why does str1 get set to "That's a Parent"?

Because overloading is (usually) determined at compile-time, not execution time. It's based purely on the compile-time types of the target and arguments, with the exception of calls using dynamic values.

In your case, the argument type is Parent, so it calls MyClassName(Parent)

Is there a way to force the code use the Child call (setting str1 to "That's a Child")?

Two options:

  • Declare p as being of type Child, not Parent
  • Declare p as being of type dynamic, which will force the overload resolution to be performed at execution time

people

See more on this question at Stackoverflow