我的代码如下,其中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");
}
}
答案 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)
您必须将其称为常规静态方法,而不是将其称为实例方法。当扩展方法同时存在编译器找到的同名实例方法时,实例方法总是“获胜”。