pup*_*eno 6 .net extension-methods .net-3.5 c#-3.0
有一个有一个方法的类,如下所示:
class Window {
public void Display(Button button) {
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
是否有可能用另一个更广泛的方法重载该方法,如下所示:
class WindowExtensions {
public void Display(this Window window, object o) {
Button button = BlahBlah(o);
window.Display(button);
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试时发生的事情是我有无限的递归.有没有办法让这项工作?我希望只有在无法调用其他方法时才调用扩展方法.
我们来看看规范吧.首先,我们必须了解方法调用的规则.粗略地说,您从您尝试调用方法的实例指示的类型开始.您继续沿着继承链寻找可访问的方法.然后,您执行类型推断和重载解析规则,并在成功时调用该方法.只有在找不到这样的方法时,才会尝试将该方法作为扩展方法处理.所以从§7.5.5.2(扩展方法调用)看,特别是粗体语句:
在其中一个表单的方法调用(第7.5.5.1节)中
expr.identifier()
expr.identifier(args)
expr.identifier<typeargs>()
expr.identifier<typeargs>(args)如果调用的正常处理找不到适用的方法,则尝试将该构造作为扩展方法调用进行处理.
除此之外的规则有点复杂,但对于简单的情况,你已经呈现给我们这很简单.如果没有适用的实例方法,则将WindowExtensions.Display(Window, object)调用扩展方法.如果参数to Window.Display是按钮或可隐式地转换为按钮,则实例方法适用.否则,将调用扩展方法(因为从中派生的所有内容都object可以隐式地转换为a object).
所以,除非有一点重要,否则你要做的就是工作.
因此,请考虑以下示例:
class Button { }
class Window {
public void Display(Button button) {
Console.WriteLine("Window.Button");
}
}
class NotAButtonButCanBeCastedToAButton {
public static implicit operator Button(
NotAButtonButCanBeCastedToAButton nab
) {
return new Button();
}
}
class NotAButtonButMustBeCastedToAButton {
public static explicit operator Button(
NotAButtonButMustBeCastedToAButton nab
) {
return new Button();
}
}
static class WindowExtensions {
public static void Display(this Window window, object o) {
Console.WriteLine("WindowExtensions.Button: {0}", o.ToString());
Button button = BlahBlah(o);
window.Display(button);
}
public static Button BlahBlah(object o) {
return new Button();
}
}
class Program {
static void Main(string[] args) {
Window w = new Window();
object o = new object();
w.Display(o); // extension
int i = 17;
w.Display(i); // extension
string s = "Hello, world!";
w.Display(s); // extension
Button b = new Button();
w.Display(b); // instance
var nab = new NotAButtonButCanBeCastedToAButton();
w.Display(b); // implicit cast so instance
var nabexplict = new NotAButtonButMustBeCastedToAButton();
w.Display(nabexplict); // only explicit cast so extension
w.Display((Button)nabexplict); // explictly casted so instance
}
}
Run Code Online (Sandbox Code Playgroud)
这将打印
WindowExtensions.Button: System.Object
Window.Button
WindowExtensions.Button: 17
Window.Button
WindowExtensions.Button: Hello, world!
Window.Button
Window.Button
Window.Button
WindowExtensions.Button: NotAButtonButMustBeCastedToAButton
Window.Button
Window.Button
Run Code Online (Sandbox Code Playgroud)
在控制台上.