Search code examples
c#inheritanceoverload-resolution

Why call object class parameter method linseed of fixed data type parameter in inheritance


Case 1:

public class BaseClass
{
    public virtual void Print(int i)
    {
        Console.WriteLine("BaseClass Print(int)");
    }
}

public class DerivedClass : BaseClass
{
    public override void Print(int i)
    {
        Console.WriteLine("DerivedClass Print(int)");
    }

    public void Print(object obj)
    {
        Console.WriteLine("DerivedClass Print(object)");
    }
}
static void Main(string[] args)
{
    DerivedClass objDerivedClass = new DerivedClass();
    int i = 10;
    objDerivedClass.Print(i);
}

Output is DerivedClass Print(object).

Case 2:

public class SomeClass
{
    public void Print(int i)
    {
        Console.WriteLine("DerivedClass Print(int)");
    }

    public void Print(object obj)
    {
        Console.WriteLine("DerivedClass Print(object)");
    }
}

static void Main(string[] args)
{
    SomeClass objSomeClass = new SomeClass();
    int i = 10;
    objSomeClass.Print(i);
}

Output is DerivedClass Print(int).

After calling objDerivedClass.Print(i); method, the output is DerivedClass Print(object). I don't understand why the method Print(object obj) is being called instead of Print(int i).

If DerivedClass does not inherit BaseClass class then output is DerivedClass Print(int).

Please explain.......


Solution

  • This is how overload resolution works with inheritance:

    1. The function that includes the override modifier is excluded from the set of candidates.
    2. Since the function with the object parameter can be used, then the function that is declared in the base is removed from the set of candidates.

    The winner is the function with the object parameter.

    According to Eric Lippert (from Microsoft):

    This is by design and for a good reason. This design helps prevent the Brittle Base Class problem. C# was designed to make it easier and safer to write "versioned" components, and this rule is a big part of that.

    When no inheritance is used, both functions are candidates, and the one that is more specific is used. The winner is the function with the int parameter.