C# 在强制转换常规参数时如何修复强制转换错误
在某些情况下,我需要将对象向下转换到接口以满足我的需要,这隐含地要求向下转换泛型接口的类型参数 例子C# 在强制转换常规参数时如何修复强制转换错误,c#,generics,inheritance,interface,C#,Generics,Inheritance,Interface,在某些情况下,我需要将对象向下转换到接口以满足我的需要,这隐含地要求向下转换泛型接口的类型参数 例子 iAge是IAnimal public interface ICage<TAnimal> where TAnimal : IAnimal<IOwner> public class Cage<TAnimal> : ICage<TAnimal> where TAnimal : IAnimal<IOwner> public
iAge
是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
哺乳动物是一种拥有者类型为IOwner
的动物
public class Human : IOwner
Human
是一种IOwner
public abstract class Mammal<TOwner> : IAnimal<TOwner>
where TOwner : 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);
var-cage=new-cage();
var me=新人类()
{
Name=“Hakim”
};
var dog=新的dog();
狗的主人=我;
笼。添加((哺乳动物)狗);
在最后一行中,我得到一个编译时错误CS0030,告诉我不能将Dog转换为Mammel。这也是原因 假设在
哺乳动物
中有一个名为所有者
的属性,如下所示:
public TOwner Owner { get; set; }
public interface IAnimal {
IOwner Owner { get; }
}
public abstract class Mammal : IAnimal { ... }
public class Dog : Mammal { ... }
对于哺乳动物的实例,它变成:
public IOwner Owner { get; set; }
狗
是一种狗
,也是一种哺乳动物
。如果您可以将dog
转换为哺乳动物
,这意味着dog.Owner
可以突然存储实现ioowner
的任何类型。i、 e.这是可能的:
class EvilOwner : IOwner { ... }
Mammal<IOwner> mammal = (Mammal<IOwner>)dog;
mammal.Owner = new EvilOwner();
有趣的是,今天早些时候出现了这个问题的一个版本:。那被发现是一个复制品。我特别喜欢@vc74对今天问题的评论:如果第二个在任何界面上工作,你就可以调用List.Add(fish)
,使用Panther
和fish
实现IAnimal
。你的情况更难,我想你可以用尼安德特人的IOwner
实现IOwner
如果你在cage
定义中使用特定类型,它应该可以工作:var cage=new cage()
然后只需将dog
传递到Add
方法,无需任何施法。或者,您可以将这两个参数设置为通用参数,例如:var-cage=new-cage()
也应该可以。@Rufus L:使用显式转换运算符是一个选项,您根本不需要强制执行。根据您的建议,我获得了一些灵活性,但失去了举例说明狗必须有人作为主人的能力。(您可以在IAnimal上设置SetOwner(IOOwner)方法并执行某种类型的检查/转换,但这并不理想)。@Hakim则无法将Dog
转换为哺乳动物。如果允许的话,你可以将狗的主人设置为人类以外的其他人,不是吗?你说得没错,但是如果在里面施放物品的话,这是可能的@哈基姆,我明白了。然后,您必须使用狗的实例创建狗的新实例,就像要将列表
转换为列表
一样,您需要创建一个新列表。在那之后,投给哺乳动物。