[英]How to iterate over items of a list when I only have access to the object of that list and dont know the type parameter?
Somewhere in my code I have an object that I already know that is a list. 在代码中的某个地方,我有一个我已经知道的对象,它是一个列表。 But I don't know the type parameter of that list.
但我不知道该列表的类型参数。 I need to iterate over it's items.
我需要遍历它的物品。 I tried to cast that object to a list of objects but it didn't help me:
我试图将该对象转换为对象列表,但并没有帮助我:
List<Object> objList = (List<Object>)(dataModel.Value);
foreach (var item in objList)
{
Console.WriteLine(item.ToString());
}
In the above code, the Value
property of dataModel
is a list of XYZ
values, but it throws an exception when I run this code. 在上面的代码中,
dataModel
的Value
属性是XYZ
值的列表,但是在运行此代码时会引发异常。 It says that, it could not cast XYZ
to Object
. 它说,它不能将
XYZ
为Object
。
Is that possible to do some deserialization and do the job over deserialized objects? 是否可以进行反序列化并对反序列化的对象进行处理?
You should cast to IEnumerable<object>
, or even just IEnumerable
. 您应该强制转换为
IEnumerable<object>
,甚至只是IEnumerable
。
A List<string>
is not a List<object>
as generic variance doesn't apply to classes, and a List<string>
is not an IList<object>
as IList<T>
is not covariant. List<string>
不是List<object>
因为通用差异不适用于类,并且List<string>
不是IList<object>
因为IList<T>
不是协变的。 (It can't be, due to operations which accept a T
, such as Add
.) (由于接受
T
操作(例如Add
),所以不能这样。)
However, IEnumerable<T>
is covariant in T
which is exactly what you want in this case - but only if your value is a list of reference types; 但是,
IEnumerable<T>
在T
中是协变的,这正是您在这种情况下想要的-但仅当您的值是引用类型的列表时; covariance doesn't work with type arguments which are value types... so a List<int>
isn't convertible to IEnumerable<object>
. 协方差不适用于值类型的类型参数...因此
List<int>
不能转换为IEnumerable<object>
。 It is still convertible to IEnumerable
though, so the following code gives you the most flexible solution: 它仍然是转换为
IEnumerable
,虽然,所以下面的代码为您提供了最灵活的解决方案:
var items = (IEnumerable) dataModel.Value;
foreach (var item in items)
{
Console.WriteLine(item);
}
A List<Something>
does not derive from List<object>
it derives from object
but not from List<object>
, this makes sense as it could be very type unsafe. List<Something>
不是从List<object>
派生的,它不是从object
派生的,而是不是从List<object>
派生的,这很有意义,因为它可能是非常不安全的类型。 You can always treat a List<int>
as an object
for example, but if you could treat it as a List<object>
you could then call .Add("test")
and end up with a List<int>
containing a string
violating type safety. 例如,您始终可以将
List<int>
视为object
,但是如果可以将其视为List<object>
,则可以调用.Add("test")
并最终得到包含string
的List<int>
违反类型安全。
However recent .net versions added covariance and contravariance, it doesn't make sense on List<T>
but it DOES make sense on IEnumerable<T>
(as you can't "add" to an IEnumerable
but only enumerate it, it's very fine to enumerate items of arbitrary types as objects
). 但是,最新的.net版本添加了协方差和逆方差,它在
List<T>
上没有意义,但在IEnumerable<T>
上却有意义(因为您不能“添加”到IEnumerable
但只能枚举它,这非常可以将任意类型的项目枚举为objects
)。
So you can cast to the interface: 这样就可以强制转换为接口:
IEnumerable<Object> objList = (IEnumerable<Object>)(dataModel.Value); // This works, List<whatever> is IEnumerable<whatever>, IEnumerable<whatever> can safely be cast to IEnumerable<object>
Or you can cast the individual items themselves if you want to stick to a List by creating a new List as such: 或者,如果您要坚持使用列表,可以自己创建单个列表,如下所示:
List<object> objlist = dataModel.Value
.Cast<object>() // every item will be cast to object
.ToList(); // then make a new list out of it, this is type safe as the original List<whatever> is not affected.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.