繁体   English   中英

我需要一个Linq IEnumerable <>。Cast(typeof(T))

[英]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()调用,则此方法应该与您的委托一起使用。 我同时实现了CastAsTypeToListOfType方法,以便您可以选择取消收藏集的迭代。 我会为将来的读者指出,这些仅在像您这样将结果动态传递给委托人的情况下才有用-在所有其他情况下,首选Cast<T>操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM