C# 如何强制转换实现接口的具体类列表
我有一个接口IAnimal和两个类(Dog、Cat),它们都实现了接口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类,如下面的
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);
}