我有一些類如下:隱泛型類型轉換不匹配重載方法簽名
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被用作類型參數「特羅」(特羅)」。沒有從「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
除了醜陋,它給了我同樣的問題(似乎匹配第一次重載)。
謝謝,但我不會跟着你。根據我的理解,你的答案'GetName((RowListItem)bar)'也應該失敗,因爲它不是從'RowListItem '派生的。但是,它成功了,因爲where TRow:BaseRow約束條件與任何從BaseRow繼承的TRow匹配。我的問題是,是否有一個原因,即使第一個從第二個繼承?編譯器不能隱式地從'SpecificRowListItem'轉換爲'RowListItem '? –
我基於您的示例在c#中利用協變量來添加一個工作示例給我的答案。 但我不能夠正確地解釋給你,因爲我不完全理解自己由xD 但有很多閱讀有關在互聯網上的東西:d – keydon
我很高興你不明白它須─ - 讓我覺得自己少了一個doofus ;-) [This link](http://stackoverflow.com/a/9381751/4062628)也很有趣。 –