簡體   English   中英

泛型約束在C#中似乎不起作用

[英]Generics constraint doesn't appear to work in C#

error CS0029: Cannot implicitly convert type `Manager<T>' to `Manager<Asset>'

我不明白為什么我在下面的代碼中遇到上述編譯時錯誤。 由於與Manager關聯的T類型必須從Asset派生,所以它行不通嗎?

public class Manager<T> where T : Asset
{
    public Manager()
    {
        var t = new Test();
        t.Manager = this; //compile-time error
    }
}

public class Test
{
    public Manager<Asset> Manager;
}

由於與Manager關聯的T類型必須從Asset派生,所以它行不通嗎?

不可以,因為通用類中的類型參數不是協變的 也就是說,如果您具有DerivedAsset : Asset ,則不允許您分配Manager<Asset> manager = new Manager<DerivedAsset>()

您可以使用out T使類型參數協變,但這僅適用於接口。 因此,您將需要以下內容:

public interface IManager<out T> where T : Asset { }

public class Test
{
    public IManager<Asset> Manager;
}

現在您應該能夠編寫原始代碼,使Manager<T>實現IManager<T>

public class Manager<T> : IManager<T> 
    where T : Asset
{
    public Manager()
    {
        var t = new Test();
        t.Manager = this;     // ok, because T in IManager<T> is covariant
    }
}

(如@sjkm指出,你也可以簡單地做一個投: t.Manager = (Manager<Asset>)this;但如果你是確保這只會工作TManager<T>從來都不是一個派生類- -例如,如果Asset被密封。)

僅僅因為TAsset並不意味着Manager<T>Manager<Asset> 如果Manager<T>T是協變的,但在C#中類不能是協變的(僅接口和委托可以),這將起作用。

相反,您也可以使Test通用:

public class Test<T> where T : Asset
{
    public Manager<T> Manager;
}

現在它應該可以按預期工作了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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