Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/194.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 - Fatal编程技术网

C# 如何强制转换实现接口的具体类列表

C# 如何强制转换实现接口的具体类列表,c#,generics,C#,Generics,我有一个接口IAnimal和两个类(Dog、Cat),它们都实现了接口 public interface IAnimal { int Age { get; set; } } public class Dog : IAnimal { public int Age { get; set; } } public class Cat : IAnimal { public int Age { get; set; } } 另外,我还有一个AnimalsManager类,如下面的

我有一个接口IAnimal和两个类(Dog、Cat),它们都实现了接口

public interface IAnimal
{
    int Age { get; set; }
}

public class Dog : IAnimal
{
    public int Age { get; set; }
}

public class Cat : IAnimal
{
    public int Age { get; set; }
}
另外,我还有一个AnimalsManager类,如下面的代码所示

public class AnimalsManager
{
    private readonly List<Dog> _dogs = new List<Dog>();
    private readonly List<Cat> _cats = new List<Cat>();

    public void SetTargetAnimalsAge(bool isDog, int age)
    {
        if (isDog)
        {
            setAnimalsAge(_dogs, age);
        }
        else
        {
            setAnimalsAge(_cats, age);
        }
    }

    private static void setAnimalsAge<T>(IEnumerable<T> animals, int age) where T : class, IAnimal
    {
        foreach (var animal in animals)
        {
            animal.Age = age;
        }
    }
}
公共类动物管理器
{
私有只读列表_dogs=新列表();
私有只读列表_cats=new List();
public void SetTargetAnimalsAge(bool isDog,int age)
{
if(isDog)
{
setAnimalsAge(狗,年龄);
}
其他的
{
设置动物年龄(_猫,年龄);
}
}
私有静态void setAnimalsAge(IEnumerable animals,int age),其中T:class,IAnimal
{
foreach(动物中的动物变量)
{
动物。年龄=年龄;
}
}
}
在方法SetTargetAnimalsAge中,setAnimalsAge会根据isDog参数的值使用两次。我想把这两个用法合并成一个,但是下面的代码不能编译

// Do not compile.
// var animals = isDog ? _dogs : _cats;
// var animals = isDog ? _dogs as List<IAnimal> : _cats as List<IAnimal>;

setAnimalsAge(animals, age);
//不要编译。
//var=isDog_狗:猫;
//var=isDog_狗为列表:猫为列表;
setAnimalsAge(动物,年龄);

如何将猫狗列表作为动物列表处理

请不要列出两个单独的清单,一个给狗,一个给猫
animalmanager
应该只知道
IAnimal
。 坚持使用接口&因此

公共类动物管理器
{
私有只读列表_animals=new List();
public void SetTargetAnimalsAge(int年龄)
{
设置动物年龄(_动物,年龄);
}
私有静态void setAnimalsAge(IEnumerable animals,int age),其中T:class,IAnimal
{
foreach(动物中的动物变量)
{
动物。年龄=年龄;
}
}
}

您不能将其作为
IList
使用,因为
IList
不是协变的,但
IEnumerable
是协变的。您可以将其强制转换为
IEnumerable
,这样应该可以工作

例如,以下代码应该可以工作:

public void SetTargetAnimalsAge(bool isDog, int age)
{   
     var animals = isDog ? (IEnumerable<IAnimal>)_dogs : _cats;
     setAnimalsAge(animals, age);
}
public void SetTargetAnimalsAge(bool-isDog,int-age)
{   
var动物=isDog?(IEnumerable)\u狗:\u猫;
setAnimalsAge(动物,年龄);
}

如果您只想设置某个类型的年龄,您可以将类型参数发送到
SetTargetAnimalAge
。谢谢您的回答。直到最近我才知道依赖倒置。我需要了解更多。@SimpleVar,是的,只要
AnimalsManager
只处理
IAnimal
就可以了。但是如果
animalmanager
知道了
IAnimal
的扩展,或者根据“IAnimal”的类型有一个
开关,那么这是检查设计的标志。@user4134476,它是可靠的原则之一,您可以在这里阅读更多内容-非常感谢<代码>isDog_狗:把猫列为名单是不可能的,但是是什么_狗:(你把猫当作IList
isDog)_狗:_猫作为i集合
isDog_狗:_猫如IEnumerable
都是可能的!!
public void SetTargetAnimalsAge(bool isDog, int age)
{   
     var animals = isDog ? (IEnumerable<IAnimal>)_dogs : _cats;
     setAnimalsAge(animals, age);
}