我正在尝试通过创建一个同名的扩展方法来修改现有扩展方法的行为。只要方法签名不同,我知道这是可能的。我也知道调用哪个方法是基于签名的“接近程度”。
如果我有:
public void DoStuff(this List<string> list) {
//...
}
并且
public void DoStuff<T>(this List<T> list) {
//...
}
我知道当调用 new List<string>().DoStuff()
时会调用 DoStuff
,而当调用new List<int>().DoStuff()
时会调用DoStuff<T>
。
但是我不明白为什么在使用接口时没有看到相同的行为。
public interface IBar { }
public class Foo : IBar
{
}
public static class FooHelper
{
public static void DoStuff(this IBar stuff)
{
Console.WriteLine("public static void DoStuff (this IBar stuff)");
}
public static void DoStuff<T>(this T stuff)
{
Console.WriteLine("public static void DoStuff<T>(this T stuff)");
}
}
class Program
{
static void Main(string[] args)
{
var foo = new Foo();
foo.DoStuff();
}
}
在上面的例子中,我期望
public static void DoStuff (this IBar stuff)
被输出,但是实际却得到了public static void DoStuff<T>(this T stuff)
。我假定接口类型比泛型类型更具体,因此对于我的
DoStuff
调用而言是更好的选择。为什么泛型类型签名会优先于接口类型签名?
IBar foo = new Foo();
),那么它将按您所需的方式执行。我猜想您只需要阅读C#规范中的重载规则,就能发现为什么会选择一个而不是另一个。如果您想知道为什么做出这个设计选择,那就是另外一回事了……最后,我认为Eric Lippert 写了一些关于重载决策的文章,可能会涉及到这个问题。 - Chris