27

我有类似的代码

public class TestA
{
    public string ColA { get; set; }
    public string ColB { get; set; }
    public string ColC { get; set; }
    public void MethodA()
    {
        MessageBox.Show("Original A1.");
    }
}

static class ExtenstionTest
{
  
    public static void MethodA(this TestA A1)
    {
        MessageBox.Show("Extended A1.");
    }
}

现在,如果我像这样调用 MethodA

TestA a = new TestA();
        a.MethodA();

它总是会调用 Original 方法。如何调用扩展方法。

4

5 回答 5

41

您不能将扩展方法作为普通扩展方法调用。实例方法覆盖具有相同签名的扩展方法

编辑:

您可以将其称为静态方法

ExtensionTest.MethodA(a);
于 2012-11-23T06:57:44.210 回答
18

您不能将其称为扩展方法。就作为一种扩展方法而言,它在这一点上基本上没用。(我个人希望这是一个警告,但没关系。)

编译器在尝试解析扩展方法之前尝试所有可能的实例方法。从 C# 4 规范的第 7.6.5.2 节:

在一种形式的方法调用中[...],如果调用的正常处理没有找到适用的方法,则尝试将构造处理为扩展方法调用。

然后:

上述规则意味着实例方法优先于扩展方法

你可以像普通的静态方法一样调用它:

// Fixed typo in name
ExtensionTest.MethodA(a);
于 2012-11-23T06:59:25.103 回答
8

扩展方法 - MSDN

永远不会调用与接口或类方法具有相同名称和签名的扩展方法。在编译时, 扩展方法的优先级总是低于类型本身定义的实例方法。

您可以将扩展方法称为类的常规静态方法。

ExtenstionTest.MethodA(a);

来自MSDN

换句话说,如果一个类型有一个名为 Process(int i) 的方法,并且你有一个具有相同签名的扩展方法,编译器将始终绑定到实例方法。当编译器遇到方法调用时,它首先在类型的实例方法中查找匹配项。如果未找到匹配项,它将搜索为该类型定义的任何扩展方法,并绑定到它找到的第一个扩展方法。下面的示例演示了编译器如何确定要绑定到哪个扩展方法或实例方法。

于 2012-11-23T06:59:17.577 回答
3

您可以像任何其他静态方法一样调用扩展方法:

ExtenstionTest.MethodA(a);
于 2012-11-23T06:58:36.707 回答
0

正如其他人建议的那样,您不能调用此方法。调用它的唯一方法是:

TestA a = new TestA();
ExtenstionTest.MethodA(a);
于 2012-11-23T07:07:37.937 回答