我有一个接口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;
}
}
}
在方法SetTargetAnimalsAge中,setAnimalsAge使用两次,具体取决于isDog参数的值。我想将这2个用法统一为1,但以下代码无法编译。
// Do not compile.
// var animals = isDog ? _dogs : _cats;
// var animals = isDog ? _dogs as List<IAnimal> : _cats as List<IAnimal>;
setAnimalsAge(animals, age);
如何处理狗和猫的一个列表作为IAnimal列表?
答案 0 :(得分:3)
请不要制作2个单独的列表,一个用于dog&amp;一只猫。 AnimalsManager
应该只知道IAnimal
。
坚持接口&amp;因此Dependency inversion
public class AnimalsManager
{
private readonly List<IAnimal> _animals = new List<IAnimal>();
public void SetTargetAnimalsAge(int age)
{
setAnimalsAge(_animals, age);
}
private static void setAnimalsAge<T>(IEnumerable<T> animals, int age) where T : class, IAnimal
{
foreach (var animal in animals)
{
animal.Age = age;
}
}
}
答案 1 :(得分:2)
您不能将其作为IList<T>
,因为IList<T>
不是协变的,但IEnumerable<T>
是协变的。您可以将其投射到IEnumerable<T>
,这应该可以。
例如,以下代码应该有效:
public void SetTargetAnimalsAge(bool isDog, int age)
{
var animals = isDog ? (IEnumerable<IAnimal>)_dogs : _cats;
setAnimalsAge(animals, age);
}