在 parent class 上创建的调用扩展方法在 child class 中重载
Call extension method created on parent class overloaded in child class
我有如下代码,其中 WebServiceSender 是 parent class。
我已经为此添加了一个扩展方法 "ExtTest"。
我有一个childclass"ChildWebServiceSender"继承
WebServiceSender.
在我的 child class 中,我有一个与签名相同的方法
扩展方法,public WebServiceSender ExtTest(string something)
现在,在创建 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。你需要这个实际上是一种代码味道,使你的代码不太可读。
我有如下代码,其中 WebServiceSender 是 parent class。
我已经为此添加了一个扩展方法 "ExtTest"。
我有一个childclass"ChildWebServiceSender"继承 WebServiceSender.
在我的 child class 中,我有一个与签名相同的方法 扩展方法,
public WebServiceSender ExtTest(string something)
现在,在创建 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。你需要这个实际上是一种代码味道,使你的代码不太可读。