To explain how it works for the OverriddenDerivedClass
example:
Have a look at the C# spec for member lookup here: http://msdn.microsoft.com/en-us/library/aa691331%28VS.71%29.aspx
That defines how the lookup is done.
In particular, look at this part:
First, the set of all accessible (Section 3.5) members named N declared in T and the base types (Section 7.3.1) of T is constructed. Declarations that include an override modifier are excluded from the set.
In your case, N
is Foo()
. Because of Declarations that include an override modifier are excluded from the set
then the override Foo(int i)
is excluded from the set.
Therefore, only the non-overridden Foo(double i)
remains, and thus it is the one that is called.
That is how it works for the OverriddenDerivedClass
example, but this is not an explanation for the DerivedClass
example.
To explain that, look at this part of the spec:
Next, members that are hidden by other members are removed from the set.
The Foo(double i)
in DerivedClass
is hiding the Foo(int i)
from the base class, so it is removed from the set.
The tricky thing here is the part that says:
All methods with the same signature as M declared in a base type of S are removed from the set.
You might say "But wait! Foo(double i)
doesn't have the same signature as Foo(int i)
, so it shouldn't be removed from the set!".
However, because there is an implicit conversion from int to double, it is considered to have the same signature, so Foo(int i)
is removed from the set.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…