[英]Why can't you cast a constrained open generic typed to the constrained type?
[英]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是有效的嗎? 或者我在這里缺少什么?
假設你還有一個類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;
}
}
你可以從Animal
為IAnimal
,從IAnimal
為Dog
,但它會拋出InvalidCastException
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.