在子类中重载的父类上创建的调用扩展方法

时间:2017-01-17 15:24:29

标签: c# .net oop extension-methods

  • 我的代码如下,其中WebServiceSender是父类。

  • 我已将“扩展”方法添加为“ExtTest”。

  • 我有一个子类“ChildWebServiceSender”继承 WebServiceSender。

  • 在我的子课程中,我有一个方法具有相同的签名 扩展方法public WebServiceSender ExtTest(string something)

现在创建Child类的对象后,我得到了intellisense,因为有两个OVERLOADED方法。但是我总是可以从Child类调用ExtTest而不是Extension方法。

如何调用Extension方法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");
    }
}

3 个答案:

答案 0 :(得分:6)

  

如何调用Extension方法ExtTest?

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

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

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

执行时类型d并不重要 - 只有编译时类型。

如果您还需要从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");

或者,更好的是,您可以重命名您的扩展方法或实例方法,以便它们不会发生冲突 - 这将使任何人读取代码更加清晰。重新打电话。

答案 1 :(得分:1)

如果要调用扩展方法,则应该从基类转换并调用它:

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

你肯定可以从你的扩展类中明确地说出来:

util.ExtTest(d, "tra");

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

答案 2 :(得分:0)

您必须将其称为常规静态方法,而不是将其称为实例方法。当扩展方法同时存在编译器找到的同名实例方法时,实例方法总是“获胜”。