![](/img/trans.png)
[英]Why do I need to cast IDictionary<T, HashSet<S>> to IDictionary<T, IEnumerable<S>>?
[英]I need a Linq IEnumerable<>.Cast(typeof(T))
我正在查询数据结构,结果类型为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 ...)
等均不起作用。
您可以使用反射调用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 });
尝试完成以下操作:
.ToList<IEntry>()
例如,如果您执行以下操作:
int [] text = {01,2,3,4,5};
List<string> list = text.Select(x => x.ToString()).ToList<string>();
根据您的反馈并使用其他答案,我创建了一个ToListOfType()
扩展方法,该方法应该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 });
}
}
如果您ToListOfType(queryClause.Type)
替换ToList()
调用,则此方法应该与您的委托一起使用。 我同时实现了CastAsType
和ToListOfType
方法,以便您可以选择取消收藏集的迭代。 我会为将来的读者指出,这些仅在像您这样将结果动态传递给委托人的情况下才有用-在所有其他情况下,首选Cast<T>
操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.