如何在 C# 中将列表或数组转换为子类型?
Posted
技术标签:
【中文标题】如何在 C# 中将列表或数组转换为子类型?【英文标题】:How to cast a list or array to a subtype in C#? 【发布时间】:2021-06-22 03:13:37 【问题描述】:我有一个包含对象列表成员的类。假设我有一个 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();
即使我可以检查所有成员都是猫。有没有更优雅的方法来做到这一点?
【问题讨论】:
***.com/questions/1297231/… - 这会有帮助吗? 这能回答你的问题吗? convert a list of objects from one type to another using lambda expression 如果你确定你的数组只包含猫,var output = data.Cast<Cat>()
。如果你只是想带猫出去,var output = data.OfType<Cat>()
@MarkusE 这是一个稍微不同的问题,因为这个问题是关于将字符串解析为整数,而这个问题只是一个普通的引用转换。 Sinatr,好问题,但所有的答案都有点垃圾。最接近的,使用Cast<T>()
,使用new List<T>(x.Cast<T>())
而不是x.Cast<T>().ToList()
,并隐藏在噪音中
The list will always contain only Dogs or only Cats but i do not know up front.
。如果你不得不这么说,那么你对多态性的使用本质上是错误的。如果它始终是T : A
或T : B
的可枚举列表,您可能应该在某处使用generics,或者重组您在某处使用多态性的方式。
【参考方案1】:
你可以这样做:
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 的评论。对我来说,这个列表只包含一个子类型似乎有点奇怪。
【讨论】:
感谢所有 cmets 和这个详细的答案,这就是我想要的。用例是最后我想为外部接口构建一个 JSON 对象,该对象本身设计得很糟糕,因为它根据上下文接受同名的不同数据类型。所以我可以选择以一种不太好的方式将它映射到有一些重复的对象(我做了),或者我可以做很好的多态性,然后在我尝试将我的对象转换为外来 JSON 时做一些额外的 Json 争吵。但该代码对我来说更难维护。以上是关于如何在 C# 中将列表或数组转换为子类型?的主要内容,如果未能解决你的问题,请参考以下文章