簡體   English   中英

具有泛型類的泛型函數:無隱式引用轉換

[英]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# 不允許泛型參數替換,即使它們是繼承類。 添加差異修飾符后,這種情況發生了變化

您需要的是協方差,它允許使用派生類型代替泛型參數。 但是方差修飾符僅適用於接口和委托,因此CaCbCc應該是允許這樣做的接口。 所以你能得到的最接近的是:

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);
    }
}

注意CaCb定義中的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM