Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is C# calling the wrong overload?

Tags:

c#

overriding

I have following code that really does funny stuff:

class Parent {
    public virtual void DoSomething(IEnumerable<string> list) {
        Console.WriteLine("Parent.DoSomething(IEnumerable<string>)");
    }
}

class Child : Parent {
    public override void DoSomething(IEnumerable<string> list) {
        Console.WriteLine("Child.DoSomething(IEnumerable<string>)");
    }

    public void DoSomething(IEnumerable<object> list) {
        Console.WriteLine("Child.DoSomething(IEnumerable<object>)");
    }
}

As you can see, the DoSomething method in Child is overridden correctly.

The output of the following code is very unexpected:

...
Child c = new Child();
var list = new List<string> { "Hello", "World!" };
c.DoSomething(list);
...

Prints Child.DoSomething(IEnumerable<object>)

Whereas assinging a Parent reference to c generates the correct output:

...
Parent c = new Child();
var list = new List<string> { "Hello", "World!" };
c.DoSomething(list);
...

Prints Child.DoSomething(IEnumerable<string>)

Why does this happen?!

like image 817
Faizan S. Avatar asked Nov 09 '10 07:11

Faizan S.


People also ask

Why is it named C?

C is a general purpose computer programming language developed in 1972 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating system. It was named 'C' because many of its features were derived from an earlier language called 'B'.

Why do we use C?

The programs that you write in C compile and execute much faster than those written in other languages. This is because it does not have garbage collection and other such additional processing overheads. Hence, the language is faster as compared to most other programming languages.

Why is C not A or B?

Because C comes after B The reason why the language was named “C” by its creator was that it came after B language. Back then, Bell Labs already had a programming language called “B” at their disposal.

What is called C language?

C is an imperative procedural language supporting structured programming, lexical variable scope, and recursion, with a static type system. It was designed to be compiled to provide low-level access to memory and language constructs that map efficiently to machine instructions, all with minimal runtime support.


1 Answers

It happens because the C# compiler obeys the spec :)

The specification says that if any method declared in a derived type is applicable, any methods originally declared in a base class (even if they're overridden in the derived type) are removed from the set of candidates.

Now because you're using C# 4 (presumably) there's an implicit conversion from List<string> to IEnumerable<object> so your Child.DoSomething(IEnumerable<object>) overload is applicable, and the compiler never really considers the one using IEnumerable<string>.

I have an article about overloading which goes into this and some other oddities.

I advise you not to overload across type hierarchies - it's confusing.

like image 197
Jon Skeet Avatar answered Oct 27 '22 00:10

Jon Skeet