【问题标题】:Reflection, Casting List<Int32> to IEnumerable<object>反射,将 List<Int32> 转换为 IEnumerable<object>
【发布时间】:2026-01-09 02:35:01
【问题描述】:

我有一个类,我需要通过对象属性来反映并检查值和其他内容。当我有一个列表并尝试将项目转换为 IEnumerable 时,一切似乎都在工作异常。

if (propType.GetInterfaces().Contains(typeof(IEnumerable)))
{
    var value = prop.GetValue(source);
    Type underlyingType = propType.GetGenericArguments()[0];

    var enumerable = value as IEnumerable<object>;
    if(enumerable == null)
    {
        // problem here......
    }

    // Check the items in the list
}

propType 返回为:

FullName = "System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"

底层类型返回为:

System.Int32

当它是一个自定义类的列表时,这很有效,当它是一个值类型时,它似乎会被破坏。

有人可以帮忙吗?

【问题讨论】:

  • 你可以推理出来。访问列表元素需要转换为对象。简单的列表包含引用类型,它们直接继承自object。绝对不是简单的值类型,元素必须是boxed。装箱转换需要代码,但该代码不存在。

标签: c# .net


【解决方案1】:

int 是一个值类型这一事实在这里有所不同。根据 C# 规范,泛型类型之间必须存在引用或身份转换才能使类型变体可转换:

如果类型 T&lt;A1, …, An&gt; 可以方差转换为类型 T&lt;B1, …, Bn&gt; T 是使用变体声明的接口或委托类型 类型参数T&lt;X1, …, Xn&gt;,以及每个变体类型参数Xi 以下条件之一:

  • Xi 是协变的,存在从 AiBi 的隐式引用或身份转换
  • Xi 是逆变的,存在从 BiAi 的隐式引用或身份转换
  • Xi 是不变的,并且存在从 AiBi 的身份转换

IEnumerable&lt;T&gt; 是协变的,所以我标记的行很重要。 Ai 在您的情况下是 intBiint。没有从intobject 的引用转换,因为int 不是引用类型。这两者之间也没有身份转换,因为它们并不相同。

我不知道您问题的全部内容,但您可以使用非通用 IEnumerable 代替 IEnumerable&lt;object&gt;。它们几乎相同。但是,您在这里可能会遇到 XY 问题,因此如果不了解您的案例,就很难为您提供帮助。

【讨论】: