开发者

Why this method called?

开发者 https://www.devze.com 2023-02-14 05:34 出处:网络
using System; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var a = new Derived();
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var a = new Derived();
            int x = 123;
            a.Foo(x);
        }
    }

    public class Base
    {
        public virtual void Foo(int x)
        {
            Console.WriteLine("Base::Foo");
        }
    }

    public class Derived : Base
    {
        public override void Foo(int x)
        {
            Console.WriteLine("Derived::Foo(int x)");
        }

        public void Foo(开发者_Go百科object o)
        {
            Console.WriteLine("Derived::Foo(object o)");
        }
    }
}

Result: "Derived::Foo(object o)"

WHY???


When the compiler tries to find candidate method signatures in preparation for overloading, it looks at the most derived type first, and removes overridden methods looking only at "freshly declared" signatures in that class.

If it finds an applicable method, it doesn't go any further up the inheritance chain to find other signatures. This is counterintuitive (at least counter to my intuition) in this sort of situation. It's designed to avoid the "brittle base class" problem, where changing the base class affects other code in unexpected ways - but when the method is actually overridden in the derived class, I can't see the benefit. (Admittedly ignoring that would mean seemingly-no-op methods which override a method just to call the base implementation weren't nearly as safely-removable as you might expect.)

I have a fairly long article going into overloading in a certain amount of detail about this situation and other corner cases - you may find it useful. See section 7.5.3 of the C# specification for more details.

Bottom line: be careful with overloading, particularly across inheritance boundaries.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号