当它是IEnumerable时,如何通过类型为"T"的对象进行枚举

7wp*_*7wp 5 c# reflection

这有点难以解释.所以这就是它.

我有这样的功能:

public T FooBar<T>(Func<T> function)
{
   T returnData = function();

   // want to iterate through returnData to do something to it

   return returnData;
}
Run Code Online (Sandbox Code Playgroud)

如果returnData(T)是一个IEnumerable列表,那么我想枚举通过returnData反射修改其内容.但我似乎无法做到这一点.当我尝试强制returnData转换为可枚举类型时,我得到一个异常:

无法转换类型的对象

'System.Collections.Generic.List`1 [汽车]'

输入

'System.Collections.Generic.List`1 [System.Object的]'.

我不会知道返回类型将是一个"汽车"列表,例如提前,仅在运行时.所以我必须检查使用反射,如果它是一个列表,然后尝试投射它,以便我可以枚举它.

除非我以错误的方式去做.returnData如果它是类型的,我该如何枚举T

use*_*116 6

一种方法是添加类型约束T,但这不是理想的:

public T FooBar<T>(Func<T> function) where T : IEnumerable
{
    // T is not strongly typed for the enumerated item
Run Code Online (Sandbox Code Playgroud)

如果你稍微改变了你的方法(wrt T):

public IEnumerable<T> FooBar<T>(Func<IEnumerable<T>> function)
Run Code Online (Sandbox Code Playgroud)

然后,您在枚举的实际项目上有强大的输入,并附加了接受可枚举对象的额外奖励.


所以我从你的问题的第二次读到中注意到,T对于你的变量的含义有一些混淆returnData.在FooBar()传递a List<Car>,Tis List<Car>,并且实际上与其List<>自身的泛型类型规范没有关联的情况下.你可以把它看作是一些List<U>地方U一些其他的,未知类型.

在运行时,你将没有简单的方法可以到达,U因为它是隐藏的,可以这么说,在里面T.你可以像其他一些回答者推荐的那样使用重载,并提供一个非IEnumerable<U>方法和一个带有类型参数的方法Func<IEnumerable<T>>.

也许有关于目标的更多细节,FooBar<T>我们可以提出一些更具体的建议.


age*_*t-j 5

if (returnData is System.Collections.IEnumerable)
{
   foreach (object o in (System.Collections.IEnumerable)returnData)
   {
      // Do something.
   }
}
Run Code Online (Sandbox Code Playgroud)

不过,真的,为什么不用这样的额外重载:

public T FooBar<T>(Func<IEnumerable<T>> function) 
Run Code Online (Sandbox Code Playgroud)