【发布时间】:2016-08-31 21:04:30
【问题描述】:
我有一些类如下:
public class RowBase { }
public class SpecificRow : RowBase { }
public class RowListItem<TRow> where TRow : RowBase { }
public class SpecificRowListItem : RowListItem<SpecificRow> { }
还有一些方法如下:
public string GetName<TRow>(RowBase row) where TRow : RowBase { }
public string GetName<TRow>(RowListItem<TRow> item) where TRow : RowBase { }
我遇到的问题是RowListItem 的子类无法匹配第二个重载的签名。以下是示例:
var foo = new SpecificRow();
var bar = new SpecificRowListItem();
var baz = new RowListItem<SpecificRow>();
string name;
name = GetName(foo); // invokes first overload as expected
name = GetName(baz); // invokes second overload as expected
name = GetName(bar); // does not compile
name = GetName((RowListItem<SpecificRow>)bar); // this alternative invokes the second overload
name = GetName<SpecificRow>(bar); // this alternative also invokes the second overload
编译错误是
错误 CS0311 类型“ConsoleApplication1.SpecificRowListItem”不能用作泛型类型或方法“Program.GetName(TRow)”中的类型参数“TRow”。没有从“ConsoleApplication1.SpecificRowListItem”到“ConsoleApplication1.RowBase”的隐式引用转换。
由于SpecificRowListItem 是RowListItem<TRow> 的子类,其TRow 满足where TRow : RowBase 约束,我希望编译器能够告诉它在提供参数时它应该匹配第二个重载该类的一个实例。但是,编译器错误的文本表明它正在尝试匹配第一个重载 (GetName(TRow))。我想了解为什么会这样,以及除了两个可行的替代方案之外,我还能做些什么来解决这个问题。我试过这个:
public string GetName<TItem, TRow>(TItem item)
where TItem : RowListItem<TRow>
where TRow : RowBase
除了丑陋之外,它给了我同样的问题(似乎与第一个重载匹配)。
【问题讨论】:
标签: c# generics implicit-conversion