in the following code I define an interface, an abstract base class with a method that prints “foo”, a class that implements both, and an extension method on the interface with a signature equal to a method in the abstract base class that prints “bar”. when I run this sample, why is “bar” printed instead of “foo”? and if applicable, what’s the morale behind this language design choice?
public interface ISomething
{}
public abstract class SomethingElse
{
public void foo()
{
Console.WriteLine("foo");
}
}
public class DefinitelySomething : SomethingElse, ISomething
{}
public static class ISomethingExtensions
{
public static void foo(this ISomething graphic)
{
Console.WriteLine("bar");
}
}
class Program
{
static void Main(string[] args)
{
ISomething g = new DefinitelySomething();
g.foo();
}
}
Because the variable is declared as
ISomething.The instance method is not known until run-time however the method overload resolution is at compile time. There’s no guarantee that the instance actually has a suitable method. In you particular example it has but that’s from a type safety perspective an irrelevant coincidence. The important type at the line
g.foo()is the type that g is declared as not the run time type