Reputation: 28151
I recently introduced an interface on a base class for unit-testing purposes and ran into a weird problem. This is the minimal reproducible scenario:
interface IBase
{
string Text { get; }
}
interface IChild : IBase
{
}
class Base : IBase
{
public string Text { get { return "Base"; }}
}
class Child : Base, IChild
{
public new string Text { get { return "Child"; }}
}
static void Main(string[] args)
{
var child = new Child();
Console.WriteLine(child.Text); // Outputs "Child"
Console.WriteLine((child as Base).Text); // Outputs "Base"
Console.WriteLine(((child as Base) as IBase).Text); // Outputs "Child"
}
The output of the first two Console.WriteLine
commands is logical, but I fail to accept the output of the last one, it even outputs Child
when using a temporary variable of type Base
. Can anyone explain what is happening here?
UPDATE
By removing the interface IChild
, ((child as Base) as IBase).Text
suddenly results in "Base"
. Which makes me conclude that, as long as Child
implements IBase
(directly or through interface inheritance) the result will be "Child"
instead of "Base"
.
This can get really tricky when you refactor a method in an other class to take an argument of IBase
instead of Base
, as it suddenly results in different behavior.
Upvotes: 9
Views: 142
Reputation: 23107
Basically you are casting here:
(child as Base)
to Base
and you're using Base
's Text
field. It's clear.
But in here:
(child as Base) as IBase
you are casting Child
to Base
and then to IBase
which means you are casting Child
to IBase
, which means Child
's Text
will be displayed. You are not changing the of underlying object by using as
.
So (child as Base) as IBase
here is the same as child as IBase
.
EDIT:
Edited question does not change the fact that this answer is correct. As @InBetween said it is just changing the way how implementation of Text
property is resolved. So Child
class no longer implements IBase
directly, so now Base
's Text
would be used as best match. Basically it is just using first class implementing IBase
Upvotes: 9