Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's going on with this method overloading?

Tags:

c#

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")?

like image 900
user2023861 Avatar asked Jan 09 '23 21:01

user2023861


2 Answers

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
like image 98
Jon Skeet Avatar answered Jan 17 '23 20:01

Jon Skeet


Method overload resolution happens at compile time, while virtual method override resolution happens at run time.

Your call to MyClassName() is being resolved at compile time to the Parent overload because the type of p is Parent. Since the Child object is actually an instance of Parent too (due to inheritance) this is not a problem. (Note that p instanceof Parent is true, even if p references a Child object.)

like image 27
cdhowie Avatar answered Jan 17 '23 21:01

cdhowie