这有点难以解释.所以这就是它.
我有这样的功能:
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?
一种方法是添加类型约束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>我们可以提出一些更具体的建议.
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)
| 归档时间: |
|
| 查看次数: |
3249 次 |
| 最近记录: |