簡體   English   中英

為什么我不能將對象強制轉換為約束泛型?

[英]Why can't I cast an object to a constrained generic?

鑒於我有以下接口和一個實現它的類:

public interface IAnimal
{
    void Feed();
}

public class Animal : IAnimal
{
    public void Feed()
    {
        // feed
    }
}

當我的Animal類實現它時,為什么不能從我的具體類轉換為通用約束為IAnimal?

public class Zoo
{
    private readonly Animal animal = new Animal();

    public TAnimal GetAnimal<TAnimal>() where TAnimal : IAnimal
    {
        return (TAnimal)(this.animal); // This will not compile
    }
}

如果我將動物的野外類型更改為IAnimal而不是Animal,那么它編譯好了:

public class Zoo
{
    private readonly IAnimal animal = new Animal();

    public TAnimal GetAnimal<TAnimal>() where TAnimal : IAnimal
    {
        return (TAnimal)(this.animal); // this compiles
    }
}

或者,如果我在強制轉換為通用TAnimal之前對IAnimal進行顯式轉換,那么這也可以正常編譯:

public class Zoo
{
    private readonly Animal animal = new Animal();

    public TAnimal GetAnimal<TAnimal>() where TAnimal : IAnimal
    {
        return (TAnimal)((IAnimal)this.animal); // this compiles
    }
}

所以我的問題是 - 為什么第一個版本不起作用? 當然編譯器有足夠的信息來知道Animal實現了IAnimal,所以給定約束將它轉換為TAnimal是有效的嗎? 或者我在這里缺少什么?

Animal繼承自IAnimalTAnimal不繼承自Animal ,也來自IAnimal 如果B不從A繼承,則不能從AB ,它將類似於:

DataTable dt = new DataTable();
string str = (string)dt;

即使DataTablestringobject繼承,也不能這樣做。 要通過繼承轉換不相關的類型,您必須定義轉換運算符

假設你還有一個類Dog

public class Dog : IAnimal 
{

} 

如果你使用Dog作為TAnimal調用你的方法: GetAnimal<TAnimal>() ,你將得到如下代碼:

public class Zoo
{
    private readonly Animal animal = new Animal();

    public Dog GetAnimal()
    {
        return (Dog)this.animal;
    }
}

當然Dog不會繼承Animal所以施法是錯誤的。

然后你有第二個例子:

public class Zoo
{
    private readonly IAnimal animal = new Animal();

    public Dog GetAnimal()
    {
        return (Dog)this.animal;
    }
}

Dog正在實現IAnimal ,所以這將編譯。 但是它會在運行時拋出InvalidCastException 同樣的事情適用於第三個例子中的雙重投射:

public class Zoo
{
    private readonly Animal animal = new Animal();

    public Dog GetAnimal()
    {
        return (Dog)(IAnimal)this.animal;
    }
}

你可以從AnimalIAnimal ,從IAnimalDog ,但它會拋出InvalidCastException

暫無
暫無

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

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