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

本文关键字:列表 接口 何强制 转换 实现 | 更新日期: 2023-09-27 18:30:40

我有一个接口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 列表来处理?

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

请不要单独列出2个列表,一个用于狗,一个用于猫。 AnimalsManager应该只知道IAnimal.坚持接口,从而依赖反转

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;
            }
        }
    }
你不能

让它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);
}