2017-11-18 165 views
1

碰撞假设我们有以下4类在C#:的通用扩展方法尽管不同类型的树木

public class ClassB :ClassA 
{ 

} 

public class ClassA 
{ 
    public string Field { get; set; } 
} 

public class Class2 : Class1 
{ 

} 

public class Class1 
{ 
    public string Field { get; set; } 
} 

ClassA和ClassB的一种类型树及1级和Class2中形成另一个。

创建以下通用扩展方法,但约束一般类型的特定类型:

public static class ClassAExtensions 
{ 
    public static T Field<T>(this T opts, string field) where T : ClassA 
    { 
     opts.Field = field; 
     return opts; 
    } 
} 
public static class Class1Extensions 
{ 
    public static T Field<T>(this T opts, string field) where T : Class1 
    { 
     opts.Field = field; 
     return opts; 
    } 
} 

理论上下面的代码应,因为只有一个单一的扩展方法编译可以使用:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var instanceB = new ClassB(); 

     instanceB.Field("fed"); 
    } 
} 

但是编译器返回此错误:

The call is ambiguous between the following methods or properties: 'ClassAExtensions.Field(T, string)' and 'Class1Extensions.Field(T, string)'

是这是编译器还是代码的错误?在我看来,编译器应该能够根据类型限制来确定使用哪种扩展方法。

+1

这是扩展方法的矫枉过正。扩展方法用于特定类型,不用作通用方法。如果你真的需要'ClassA'的扩展方法,它应该被声明为'public static ClassA Field(this ClassA opts,string field)' –

回答

1

此问题已被询问次数。通用类型约束不是方法签名的一部分。

编译器,解决呼叫时,看到两个相同的候选人:

ClassAExtensions.Field<T>(this T opts, string field) 
Class1Extensions.Field<T>(this T opts, string field) 

它不能在两者之间进行选择,因为两者都是同样有效,因此标签调用模棱两可。

现在的问题可能是:这是一个合理的设计?那么,说得温和些,对这个问题有不同的看法。阅读this了解更多信息。