首页 > 解决方案 > 如何在 C# 中将列表或数组转换为子类型?

问题描述

我有一个包含对象列表成员的类。假设我有一个 Animal 基类和 Cat 和 Dog 的子类型。该列表将始终仅包含 Dogs 或 Cats,但我不知道前面。

class MyClass {

    public readonly List<Animal> Data = new();

    public void MethodForDogs()
    {
        Data.Add(new Dog());
    }

    public void MethodForCats()
    {
        Data.Add(new Cat());
    }

    public void DoSomething()
    {
        HelperClass.DoIt(Data);
    }
}

class HelperClass {

    public static void DoIt(List<Animals> data) {

        if (data[0].GetType() == typeof(Cat) ) {
            var arrayCats = new Cat[data.Count];
            int i = 0;
            foreach (Animal item in data) {
                arrayCats[i++] = (Cat) item;
            }
            // use arrayCats
            ..
        }
        else if (data[0].GetType() == typeof(Dog) {
           // same, then use arrayDogs
           ..
        }
    }
}

没有工作的是直接演员,比如

var arrayCats = (Cat[])data.ToArray();

即使我可以检查所有成员都是猫。有没有更优雅的方法来做到这一点?

标签: c#arrayscasting

解决方案


您可以通过以下方式进行操作:

class HelperClass
{
    public static void DoIt(List<Animals> data)
    {
         if(data.All(a => a is Dog))
         {
              Dog[] dogs = data.OfType<Dog>().ToArray();
              // do something with dogs
         }
         else if(data.All(a => a is Cat))
         {
              Cat[] cats= data.OfType<Cat>().ToArray();
              // do something with cats
         }
         else
         {
            throw new ArgumentException("data must contain items of the same type");
         }
     }
}

使用All,您检查列表中的所有项目是否满足条件(在您的情况下为类型)。OfType()让您所有具有某种类型的项目(在您的情况下:所有项目)自动转换为该类型。如果列表是混合类型,该方法将抛出异常(当然,您可以使用更适合您需要的另一种错误处理)。

但您也应该考虑@AlphaDelta 的评论。对我来说,这个列表只包含一个子类型似乎有点奇怪。


推荐阅读