我对扩展方法的工作方式有点困惑。
如果我正确地阅读了http://msdn.microsoft.com/en-us/library/bb383977.aspx和If an extension method has the same signature as a method in the sealed class, what is the call precedence?。
然后以下应该写出“Instance”,而是写出“Extension method”。
interface IFoo
{
}
class Foo : IFoo
{
public void Say()
{
Console.WriteLine("Instance");
}
}
static class FooExts
{
public static void Say(this IFoo foo)
{
Console.WriteLine("Extension method");
}
}
class Program
{
static void Main(string[] args)
{
IFoo foo = new Foo();
foo.Say();
}
}
感谢任何澄清行为的帮助。
答案 0 :(得分:14)
这里最大的区别是您已为IFoo
界面定义了扩展方法,而您的foo
变量属于IFoo
类型。
如果你的代码看起来像这样:
Foo foo = new Foo();
foo.Say()
将执行Foo.Say()方法,而不是扩展方法。
我希望我能够详细解释为什么会这样,但我只能涵盖基本机制。由于您的变量是IFoo
类型而不是Foo
,当编译器尝试确定哪些方法可用时,它会查看Foo
类的任何非接口方法(因为它应该)。但是,扩展方法Say()
可用,因此它会调用它。
答案 1 :(得分:4)
在Main
中,
foo
被声明为IFoo
。当编译器查找方法Say
时,它只找到扩展方法。这是因为实例方法在Foo
中声明,而不是在IFoo
中声明。编译器不知道变量foo
恰好包含Foo
的实例;它只是查看声明变量的类型。