[英]Why can't I cast an object to a constrained generic?
Given that I have the following interface and a class that implements it: 鉴于我有以下接口和一个实现它的类:
public interface IAnimal
{
void Feed();
}
public class Animal : IAnimal
{
public void Feed()
{
// feed
}
}
Why is it not possible to cast from my concrete class to a generic constrained to be IAnimal, when my Animal class implements it? 当我的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
}
}
If I change the field type of animal to be IAnimal rather than Animal then it compiles ok: 如果我将动物的野外类型更改为IAnimal而不是Animal,那么它编译好了:
public class Zoo
{
private readonly IAnimal animal = new Animal();
public TAnimal GetAnimal<TAnimal>() where TAnimal : IAnimal
{
return (TAnimal)(this.animal); // this compiles
}
}
Or alternatively if I do an explicit cast to IAnimal before the cast to the generic TAnimal then this will also compile fine: 或者,如果我在强制转换为通用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
}
}
So my question is - why doesn't the first version work? 所以我的问题是 - 为什么第一个版本不起作用? Surely the compiler has enough information to know that Animal implements IAnimal, so given the constraint it would be valid to cast it to TAnimal?
当然编译器有足够的信息来知道Animal实现了IAnimal,所以给定约束将它转换为TAnimal是有效的吗? Or is there something I am missing here?
或者我在这里缺少什么?
Animal
inherits from IAnimal
and TAnimal
doesn't inherit from Animal
, but from IAnimal
too. Animal
继承自IAnimal
, TAnimal
不继承自Animal
,也来自IAnimal
。 You can't cast from A
to B
if B
doesn't inherit from A
, it would be something like: 如果
B
不从A
继承,则不能从A
为B
,它将类似于:
DataTable dt = new DataTable();
string str = (string)dt;
You can't do this even though DataTable
and string
inherit from object
. 即使
DataTable
和string
从object
继承,也不能这样做。 To convert between types that aren't related by inheritance you have to define conversion operators 要通过继承转换不相关的类型,您必须定义转换运算符
Suppose you have also a class Dog
: 假设你还有一个类
Dog
:
public class Dog : IAnimal
{
}
If you invoke your method: GetAnimal<TAnimal>()
with Dog
as TAnimal
you will have a code like this: 如果你使用
Dog
作为TAnimal
调用你的方法: GetAnimal<TAnimal>()
,你将得到如下代码:
public class Zoo
{
private readonly Animal animal = new Animal();
public Dog GetAnimal()
{
return (Dog)this.animal;
}
}
Of course Dog
does not inherit from Animal
so the casting is wrong. 当然
Dog
不会继承Animal
所以施法是错误的。
Then you have your second example: 然后你有第二个例子:
public class Zoo
{
private readonly IAnimal animal = new Animal();
public Dog GetAnimal()
{
return (Dog)this.animal;
}
}
Dog
is implementing IAnimal
, so this will compile. Dog
正在实现IAnimal
,所以这将编译。 It will however throw a InvalidCastException
in runtime. 但是它会在运行时抛出
InvalidCastException
。 The same thing applies to the double casting in your third example: 同样的事情适用于第三个例子中的双重投射:
public class Zoo
{
private readonly Animal animal = new Animal();
public Dog GetAnimal()
{
return (Dog)(IAnimal)this.animal;
}
}
You can cast from Animal
to IAnimal
and from IAnimal
to Dog
, however it will throw InvalidCastException
. 你可以从
Animal
为IAnimal
,从IAnimal
为Dog
,但它会抛出InvalidCastException
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.