c# - 如何在 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();
即使我可以检查所有成员都是猫。有没有更优雅的方法来做到这一点?
解决方案
您可以通过以下方式进行操作:
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 的评论。对我来说,这个列表只包含一个子类型似乎有点奇怪。
推荐阅读
- matlab - Matlab - 三个(或更多)子图,带有单一颜色条和通用色标
- java - 在集成测试中使用 Autowire 进行数据库测试
- c++ - QListView如何支持手势滑动?
- if-statement - 如果 A 或 B 列等于 ___,则获取 C 或 D 列的最后 5 个结果?
- c++ - 如何在构造函数的成员初始化器列表中调用两个函数?
- typescript - 将一种类型的数组转换为该类型的映射对象
- makefile - 是什么导致我的 CMake 多目标模式错误?
- sql - 如何使用 SQL 查询不同的数据组
- button - 如何使用 SwiftUI 将参数传递给 Button 的操作
- sql - 用于平滑 postgresql 中缺失数据的窗口函数