在 parent class 上创建的调用扩展方法在 child class 中重载

Call extension method created on parent class overloaded in child class

现在,在创建 Child class 的 object 之后,我得到了智能感知,因为有两个重载的方法。但是我总是可以从 Child class 调用 ExtTest 而不是扩展方法。

如何调用扩展方法 ExtTest?

public class WebServiceSender : IMessageSender
{
    public void SendMessage(string subject, string body)
    {
        Console.WriteLine("Web Service\n{0}\n{1}\n", subject, body);
    }
}
public static class util 
{
    public static WebServiceSender ExtTest(this WebServiceSender abc, string something)
    {
        Console.WriteLine("I am into extension");
        return new WebServiceSender();
    }
}

public class ChildWebServiceSender : WebServiceSender
{
    public WebServiceSender ExtTest(string something)
    {
        Console.WriteLine("I am in instance");
        return new WebServiceSender();
    }
}

class Program
{
    static void Main(string[] args)
    {
        ChildWebServiceSender d = new ChildWebServiceSender();
        d.ExtTest("abc");
    }
}

How can i call Extension method ExtTest ?

实例方法总是优先于扩展方法 - 编译器仅在其他所有方法都失败后才检查扩展方法。

在这种情况下,最简单的方法就是使用 WebServiceSender 类型的变量来代替:

WebServiceSender d = new ChildWebServiceSender();
d.ExtTest("abc"); // This will call the extension method

d 的 execution-time 类型无关紧要 - 只有 compile-time 类型。

如果您还需要从 ChildWebServiceSender 调用方法,您可以只使用两个引用同一对象的变量:

ChildWebServiceSender child = new ChildWebServiceSender();
WebServiceSender baseRef = child;
child.ExtTest("abc"); // This will call the child instance method
baseRef.ExtTest("abc"); // This will call the extension method

(当然,您可以改用强制转换 - 我认为这样读起来会更清晰。要点是您需要 WebServiceSender 类型的表达式作为方法调用的目标。)

或者您可以将该方法作为常规静态方法调用:

// TODO: Rename "util" to follow .NET naming conventions
util.ExtTest(d, "abc");

或者,更好的是,您可以重命名您的扩展方法或您的实例方法,这样它们就不会发生冲突 - 这将使 阅读 您编写的代码的任何人都更加清楚正在尝试调用。

您必须像调用常规静态方法一样调用它,而不是像调用实例方法一样调用它。当编译器找到同名的扩展方法和实例方法时,实例方法总是"wins".

如果你想调用扩展方法,你应该从基础开始转换和调用它 class:

((WebServiceSender)d).ExtTest("abc");

当然你可以从你的扩展程序中显式调用它 class:

util.ExtTest(d, "tra");

我同意评论和 Jon Skeet。你需要这个实际上是一种代码味道,使你的代码不太可读。