Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why C# compiler use an invalid method's overload?

Tags:

c#

oop

I have been confused by the following code

class A {     public void Abc(int q)     {         Console.Write("A");     } }  class B : A {     public void Abc(double p)     {         Console.Write("B");     } }      ...     var b = new B();     b.Abc((int)1); 

The result of code execution is "B" written to console.

In fact the B class contains two overloads of Abc method, the first for int parameter, the second one for double. Why the compiler use a double version for an integer argument?

Be careful the method abc(double) doesn't shadow or override the method abc(int)

like image 240
Viacheslav Smityukh Avatar asked Feb 11 '16 00:02

Viacheslav Smityukh


People also ask

Why C is the best language?

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 used?

C is a general-purpose programming language and can efficiently work on enterprise applications, games, graphics, and applications requiring calculations, etc. C language has a rich library which provides a number of built-in functions. It also offers dynamic memory allocation.

Why is C used in C?

%d is used to print decimal(integer) number ,while %c is used to print character . If you try to print a character with %d format the computer will print the ASCII code of the character.

Why should you learn C?

C is very fast in terms of execution time. Programs written and compiled in C execute much faster than compared to any other programming language. C programming language is very fast in terms of execution as it does not have any additional processing overheads such as garbage collection or preventing memory leaks etc.


1 Answers

Since the compiler can implicitly convert the int to double, it chooses the B.Abc method. This is explained in this post by Jon Skeet (search for "implicit"):

The target of the method call is an expression of type Child, so the compiler first looks at the Child class. There's only one method there, and it's applicable (there's an implicit conversion from int to double) so that's the one that gets picked. The compiler doesn't consider the Parent method at all.

The reason for this is to reduce the risk of the brittle base class problem...

More from Eric Lippert

As the standard says, “methods in a base class are not candidates if any method in a derived class is applicable”.

In other words, the overload resolution algorithm starts by searching the class for an applicable method. If it finds one then all the other applicable methods in deeper base classes are removed from the candidate set for overload resolution. Since Delta.Frob(float) is applicable, Charlie.Frob(int) is never even considered as a candidate. Only if no applicable candidates are found in the most derived type do we start looking at its base class.

Things get a little more interesting if we extend the example in your question with this additional class that descends from A:

class C : A {     public void Abc(byte b) {         Console.Write("C");     } } 

If we execute the following code

int i = 1; b.Abc((int)1); b.Abc(i); c.Abc((int)1); c.Abc(i); 

the results are BBCA. This is because in the case of the B class, the compiler knows it can implicitly cast any int to double. In the case of the C class, the compiler knows it can cast the literal int 1 to a byte (because the value 1 fits in a byte) so C's Abc method gets used. The compiler, however, can't implicitly cast any old int to a byte, so c.Abc(i) can't use C's Abc method. It must use the parent class in that case.

This page on Implicit Numeric Conversions shows a compact table of which numeric types have implicit conversions to other numeric types.

like image 71
hatchet - done with SOverflow Avatar answered Oct 24 '22 03:10

hatchet - done with SOverflow