[英]Generic function with generic class: no implicit reference conversion
我試圖通過引入通用函數來清理一些重復的代碼塊。 但我沒能做到,而且我感覺我的類繼承結構比我試圖清理的代碼更混亂......
以下是所涉及類的抽象概述:
接口:
interface Ia
interface Ib : Ia
interface Ic : Ib
類:
class Ca<T> where T : Ia
class Cb<T> : Ca<T> where T : Ia
class Cc : Cb<Ic>
功能:
void F<T>(T t) where T : Ca<Ib>
無效的函數調用:
F<Cc>(my_c);
錯誤:
The type 'Cc' cannot be used as type parameter 'T' in the generic type or method 'F<T>(T)'. There is no implicit reference conversion from 'Cc' to 'Ca<Ib>'.
我在錯誤中猜到了“隱式”這個詞,我指的是在類定義中沒有where T : Ib
的事實。 所以我添加了另一個類
class Cb2<T> : Cb<T> where T : Ib
並使Cc
繼承自Cb2
而不是Cb
。 但這導致了同樣的錯誤。
誰能解釋為什么這是受限的,我該如何解決?
謝謝!
一般來說,C# 不允許泛型參數替換,即使它們是繼承類。 添加差異修飾符后,這種情況發生了變化。
您需要的是協方差,它允許使用派生類型代替泛型參數。 但是方差修飾符僅適用於接口和委托,因此Ca
, Cb
, Cc
應該是允許這樣做的接口。 所以你能得到的最接近的是:
interface Ia {}
interface Ib : Ia {}
interface Ic : Ib {}
interface Ca<out T> where T : Ia {}
interface Cb<out T> : Ca<T> where T : Ia {}
interface Cc : Cb<Ic> {}
class Main
{
void F<T>(T t) where T : Ca<Ib>
{}
void M()
{
F<Cc>(null);
}
}
注意Ca
和Cb
定義中的out T
為了使這段代碼起作用,您需要使用一個接口來啟用協方差,正如 Pavel 之前所說的那樣。 您只需要一個最高級別的。
interface ICa<out T> where T : Ia
class Ca<T> : ICa<T> where T : Ia
class Cb<T> : Ca<T> where T : Ia
class Cc : Cb<Ic>
方法簽名應該是這樣的
void F<T>(T t) where T : ICa<Ib>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.