为什么不能将对象强制转换为受约束的泛型?
本文关键字:受约束 泛型 转换 不能 对象 为什么 | 更新日期: 2023-09-27 18:16:57
假设我有以下接口和实现它的类:
public interface IAnimal
{
void Feed();
}
public class Animal : IAnimal
{
public void Feed()
{
// feed
}
}
为什么不可能从我的具体类强制转换为一般约束为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
}
}
如果我将animal的字段类型改为IAnimal而不是animal,那么它会编译ok:
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
继承IAnimal
, TAnimal
不继承Animal
,但也继承IAnimal
。如果B
不继承A
,则不能从A
强制转换为B
,它将类似于:
DataTable dt = new DataTable();
string str = (string)dt;
即使DataTable
和string
继承自object
,也不能这样做。要在没有继承关系的类型之间进行转换,必须定义转换操作符
假设您还有一个类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
,所以cast是错误的。
然后是第二个例子:
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
。