我正在查询数据结构,结果类型为IEnumerable<IEntry>
(IEntry
是一个框架接口),每个条目都有一个Data
属性(类型为object)对我来说。
我的代码如下所示:
var resultList = framework.QueryAllOfType(queryClause.Type)
.Select(e => e.Data)
.ToList();
deleagte.DynamicInvoke(new[]{resultList});
委托背后的方法看起来像这样:
void Foo (IEnumerable<SomeType> bar); // if queryClause.Type == typeof(SomeType)
void Foo (IEnumerable<OtherType> bar); // if queryClause.Type == typeof(OtherType)
我绝对肯定queryClause.Type
匹配SomeType
,当然,.NET框架不是; - )
不幸的是,这意味着resultList
的类型为IEnumerable<object>
,尽管其中的所有对象都是正确的类型,但我无法调用委托(例外:IEnumerable<object> cannot be converted into IEnumerable<SomeType>
)
我知道为什么会这样,但解决方案是什么?我需要的是:
.Select(e => e.Data).Cast(queryClause.Type).ToList()
应返回IEnumerable<queryClause.Type>
。在.NET框架中是否已存在这样的事情?有更好的解决方案吗?
重要:由于两个答案已经误解了我的意图,我不能将该类型用作通用参数,因为它仅在运行时已知。因此,所有Cast<...>()
,Select(e =e as ...)
等都无效。
答案 0 :(得分:1)
您可以使用反射调用Cast
:
var method = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(queryClause.Type);
IEnumerable<object> cSeq = (IEnumerable<object>)method.Invoke(null, new object[] { resultList });
deleagte.DynamicInvoke(new[]{ cSeq });
答案 1 :(得分:0)
尝试完成以下内容:
.ToList<IEntry>()
例如,如果您执行以下操作:
int [] text = {01,2,3,4,5};
List<string> list = text.Select(x => x.ToString()).ToList<string>();
答案 2 :(得分:0)
根据您的反馈并使用其他答案,我创建了一个ToListOfType()
扩展方法,可以满足您的需求。
public static class EnumerableExtensions
{
private static readonly Type _enumerableType = typeof(Enumerable);
public static IEnumerable CastAsType(this IEnumerable source, Type targetType)
{
var castMethod = _enumerableType.GetMethod("Cast").MakeGenericMethod(targetType);
return (IEnumerable)castMethod.Invoke(null, new object[] { source });
}
public static IList ToListOfType(this IEnumerable source, Type targetType)
{
var enumerable = CastAsType(source, targetType);
var listMethod = _enumerableType.GetMethod("ToList").MakeGenericMethod(targetType);
return (IList)listMethod.Invoke(null, new object[] { enumerable });
}
}
如果您只是用ToList()
替换ToListOfType(queryClause.Type)
来电,这应该适用于您的代理人。我实现了CastAsType
和ToListOfType
方法,以便您可以选择不迭代的集合。我将向未来的读者注意,这些仅在您将动态结果传递给委托人的情况下有用 - 在所有其他情况下,Cast<T>
操作将是首选。