在某些情况下,我需要将对象强制转换为适合我的需要的接口,这隐式要求强制转换通用接口的类型参数。
例ICage<TAnimal>
是Cage
类型的动物的IAnimal
的接口
public interface ICage<TAnimal>
where TAnimal : IAnimal<IOwner>
public class Cage<TAnimal> : ICage<TAnimal>
where TAnimal : IAnimal<IOwner>
public interface IAnimal<out TOwner>
where TOwner : IOwner
IAnimal
需要类型为IOwner
的所有者public abstract class Mammal<TOwner> : IAnimal<TOwner>
where TOwner : IOwner
哺乳动物是一种动物,拥有者的类型为
IOwner
。public class Human : IOwner
Human
是IOwner
的一种public class Dog<TOwner> : Mammal<TOwner>
where TOwner : IOwner
狗是哺乳动物的一种。
现在将所有内容放在一起:
var cage = new Cage<Mammal<IOwner>>();
var me = new Human()
{
Name = "Hakim"
};
var dog = new Dog<Human>();
dog.Owner = me;
cage.Add((Mammal<IOwner>)dog);
在最后一行,我得到一个编译时错误CS0030,告诉我我不能将Dog转换为Mammel。
最佳答案
这与you can't cast a List<string>
to a List<object>
的原因相同。
假设在Mammal
中有一个名为Owner
的属性,如下所示:
public TOwner Owner { get; set; }
对于
Mammal<IOwner>
的实例,它将变为:public IOwner Owner { get; set; }
dog
是Dog<Human>
,它也是Mammal<Human>
。如果可以将dog
强制转换为Mammal<IOwner>
,则意味着dog.Owner
可以突然存储实现IOwner
的任何类型。即这是可能的:class EvilOwner : IOwner { ... }
Mammal<IOwner> mammal = (Mammal<IOwner>)dog;
mammal.Owner = new EvilOwner();
但这是不可能的,因为在运行时
dog
是Dog<Human>
,其Owner
为Human
。 EvilOwner
可能无法存储在Human
中!我建议您执行的操作是删除
TOwner
通用参数。如果您认为Dog<Human>
也是Mammal<IOwner>
的一种,那么设计这样的类可能更有意义:public interface IAnimal {
IOwner Owner { get; }
}
public abstract class Mammal : IAnimal { ... }
public class Dog : Mammal { ... }
关于c# - 强制转换通用参数时如何解决强制转换错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53965755/