当我只能访问该列表的对象并且不知道类型参数时,如何迭代列表的项目?

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?

在我的代码中的某处,我有一个我已经知道的对象,它是一个列表。但我不知道该列表的类型参数。我需要遍历它的项目。我试图将该对象转换为对象列表,但它对我没有帮助:

List<Object> objList = (List<Object>)(dataModel.Value);
foreach (var item in objList)
{
        Console.WriteLine(item.ToString());
}

在上面的代码中,dataModelValue属性是一个XYZ值的列表,但是当我运行时抛出异常这个代码。它说,它无法将 XYZ 转换为 Object

是否可以进行一些反序列化并在反序列化的对象上完成这项工作?

您应该转换为 IEnumerable<object>,甚至只是 IEnumerable

A List<string> 不是 List<object>,因为通用方差不适用于 类,并且 List<string> 不是 IList<object>,因为 IList<T> 不是协变的。 (不可能,因为 接受 一个 T 的操作,例如 Add。)

但是,IEnumerable<T>T 中是协变的,这正是您在这种情况下想要的 - 但前提是您的值是 reference 的列表类型;协方差不适用于作为值类型的类型参数...因此 List<int> 无法转换为 IEnumerable<object>。它 不过仍然可以转换为 IEnumerable,所以下面的代码给了你最灵活的解决方案:

var items = (IEnumerable) dataModel.Value;
foreach (var item in items)
{
    Console.WriteLine(item);
}

A List<Something> 不是从 List<object> 派生的,它是从 object 派生的,而不是从 List<object> 派生的,这是有道理的,因为它可能非常不安全。例如,您始终可以将 List<int> 视为 object,但如果您可以将其视为 List<object>,则可以调用 .Add("test") 并以 List<int> 包含 string 违反类型安全。

然而最近的 .net 版本增加了协变和逆变,它在 List<T> 上没有意义,但在 IEnumerable<T> 上确实有意义(因为你不能 "add"一个IEnumerable但只枚举它,将任意类型的项枚举为objects).

是很​​好的

所以你可以转换到接口:

IEnumerable<Object> objList = (IEnumerable<Object>)(dataModel.Value); // This works, List<whatever> is IEnumerable<whatever>, IEnumerable<whatever> can safely be cast to IEnumerable<object>

或者,如果您想通过创建一个新列表来坚持一个列表,您可以自己投射各个项目:

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.