【发布时间】:2019-05-26 16:55:58
【问题描述】:
在某些情况下,我需要将对象转换为接口以满足我的需求,这隐含地需要转换泛型接口的类型参数。
示例
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 类型的 Owner
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。
【问题讨论】:
-
有趣的是,今天早些时候出现了这个问题的一个版本:stackoverflow.com/questions/53960364/…。发现它与stackoverflow.com/questions/15596005/… 重复。我特别喜欢对今天问题的评论(@vc74):如果第二个在任何接口上工作,你就可以调用
List<Panther>.Add(fish),同时Panther和Fish实现IAnimal我>。你的情况更难,我想你可以有一个Neanderthal实现IOwner -
如果您在
cage定义中使用特定类型,它应该可以工作:var cage = new Cage<Mammal<Human>>();然后只需将dog传递给Add方法而不进行任何转换。或者,您可以将两个参数设为通用,例如:var cage = new Cage<IAnimal<IOwner>>();,它也应该可以工作。 -
@Rufus L: 是否使用显式转换运算符
-
你根本不需要投射。
标签: c# generics inheritance interface