[英]How to cast a list of concrete classes which implement an interface
I have an interface IAnimal and two classes(Dog, Cat), which both implement the interface. 我有一个接口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; }
}
Also, I have an AnimalsManager class as shown in the code below. 另外,我有一个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;
}
}
}
In the method SetTargetAnimalsAge, setAnimalsAge is used twice depending on the value of isDog argument. 在方法SetTargetAnimalsAge中,根据isDog参数的值,两次使用setAnimalsAge。 I'd like to unite these 2 usages into 1, but the following codes do not compile.
我想将这两种用法合并为1,但以下代码无法编译。
// Do not compile.
// var animals = isDog ? _dogs : _cats;
// var animals = isDog ? _dogs as List<IAnimal> : _cats as List<IAnimal>;
setAnimalsAge(animals, age);
How is it possible to handle one of the lists of Dogs and Cats as a list of IAnimal? 如何将“猫狗”列表中的一个作为IAnimal列表处理?
Please dont make 2 separate lists, one for dog & one for cat. 请不要分别列出2张清单,一张代表狗,一张代表猫。
AnimalsManager
should know only about IAnimal
. AnimalsManager
应该只了解IAnimal
。 Stick to Interfaces & thus 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;
}
}
}
You can't have it as IList<T>
because IList<T>
is not covariant but IEnumerable<T>
is covariant. 您不能将其作为
IList<T>
因为IList<T>
不是协变的,而IEnumerable<T>
是协变的。 You can cast it to IEnumerable<T>
and that should work. 您可以将其
IEnumerable<T>
为IEnumerable<T>
,这应该可以工作。
For example, following code should work: 例如,以下代码应该工作:
public void SetTargetAnimalsAge(bool isDog, int age)
{
var animals = isDog ? (IEnumerable<IAnimal>)_dogs : _cats;
setAnimalsAge(animals, age);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.