Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在强制转换常规参数时如何修复强制转换错误_C#_Generics_Inheritance_Interface - Fatal编程技术网

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
转换为
哺乳动物。如果允许的话,你可以将狗的主人设置为人类以外的其他人,不是吗?你说得没错,但是如果在里面施放物品的话,这是可能的@哈基姆,我明白了。然后,您必须使用
狗的实例创建
狗的新实例,就像要将
列表
转换为
列表
一样,您需要创建一个新列表。在那之后,投给哺乳动物。