简体   繁体   English

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

[英]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.

相关问题 如何区分()列出包含实现接口的类的列表? C# - How to Distinct() List which contains classes that implement interface? C# C#如何实现具体类不同的接口? - C# How to implement interface where concrete classes differs? 为什么我不能将具体类添加到具体类实现的接口列表中? - Why can't I add concrete classes to a list of interfaces which the concrete classes implement? 如何将“类列表”转换为“其接口列表”? - How to cast a 'list of classes' to a 'list of its interface'? 有没有办法让每个实现接口 Ae 的 class 都有一个将 Ba 实现为属性的具体类的列表? - Is there any way to make each class that implements interface Ae has a List of one of the concrete classes that implement Ba as property? 如何获取实现接口的类列表? - How to obtain a list of classes that implement an interface? 如何将强制类型转换为接口 - How to type cast interface to a concrete type 如何从具体类转换为接口类型? - How to cast from a concrete class to an interface type? 将界面投射到混凝土类型 - Cast interface to concrete type 如何使用接口,基础和具体实现存储库模式 - How to implement Repository Pattern with interface, base and concrete
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM