Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusing overload resolution

I have a class that inherits from another class to allow using nullable value. But when I use it with non-nullable value​​, it uses the overload anyway for nullable.

I do not understand why the function of the class c2 mask the function of the class c1 in this code :

class c1
{
    public void fn1(int value)
    {
        Console.WriteLine("value {0} is normal", value);
    }
    public void fn1(int? value)
    {
        Console.WriteLine("value {0} is nullable", value);
    }
    public void fn2(int value)
    {
        Console.WriteLine("value {0} is normal", value);
    }
}
class c2: c1
{
    public void fn2(int? value)
    {
        Console.WriteLine("value {0} is nullable", value);
    }
}

class Program
{
    static void Main(string[] args)
    {
        c1 o1 = new c1();
        c2 o2 = new c2();
        int val = 10;
        o1.fn1(val);
        o2.fn1(val);
        o2.fn2(val);
        Console.ReadLine();
    }
}

And the result is :

value 10 is normal.
value 10 is normal.
value 10 is nullable.

However c2 has function fn2(int).

like image 695
Nathan Nau Avatar asked Aug 15 '26 13:08

Nathan Nau


2 Answers

This is what I found on Jon Skeet's blog.

Inheritance can cause a confusing effect. When the compiler goes looking for instance method overloads, it considers the compile-time class of the "target" of the call, and looks at methods declared there. If it can't find anything suitable, it then looks at the parent class... then the grandparent class, etc. This means that if there are two methods at different levels of the hierarchy, the "deeper" one will be chosen first, even if it isn't a "better function member" for the call.

http://csharpindepth.com/Articles/General/Overloading.aspx

like image 196
Han Avatar answered Aug 18 '26 02:08

Han


As is true in many edge cases, there's no divined "why" to it, it's just how the C# spec was written. They could have done it other ways, but decided to do it this way. https://msdn.microsoft.com/en-us/library/aa691336(v=vs.71).aspx

Most relevant portion (from "7.4.2 Overload resolution" of C# spec linked above, different versions of spec may have similar text in other section):

the set of candidates for a method invocation does not include ... methods in a base class are not candidates if any method in a derived class is applicable

like image 37
Dax Fohl Avatar answered Aug 18 '26 04:08

Dax Fohl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!