哪里ToList()方法? (IQueryable的)(Where is the ToList(

2019-06-27 18:28发布

如果我试试这个,它的工作:

var query = myContextObject.Users.Where(u=>u.Name == "John");
query.ToList();

我能够调用ToList和很多其他的扩展方法。

但是,如果我试试这个:

public List ConvertQueryToList(IQueryable query)
{
    return query.ToList();
}

ToList将无法访问,我猜这是因为ToList是一个扩展方法,但再怎么是, ToList附着在第一个例子? 是否有可能访问ToList在第二种情况下?

Answer 1:

你需要把它写成:

public List<T> ConvertQueryToList<T>(IQueryable<T> query)
{
    return query.ToList();
}

这将导致IQueryable<T>以返回适当的List<T>由于Enumerable.ToList()方法需要IEnumerable<T>作为输入(这也可以与IQueryable<T>IQueryable<T>继承IEnumerable<T>

话虽这么说,实在没有理由使用这种方式。 您可以随时只需调用ToList()直接,如果你需要创建一个List<T> -第二层的内部抽象只是混淆的API进一步。

如果你想转换一个非泛型的IQueryable接口,你需要做的是这样的:

public List<T> ConvertQueryToList<T>(IQueryable query)
{
    return query.Cast<T>.ToList();
}

那么这就需要呼唤这样的:

var results = ConvertQueryToList<SomeType>(queryable);

另外,如果你要离开这个非一般的(我不推荐),那么你可以使用:

public ArrayList ConvertQueryToList(IQueryable query)
{
    ArrayList results = new ArrayList();
    results.AddRange(query.Cast<object>().ToList());
    return results;
}


Answer 2:

首先你的例子返回IQueryable<T>而在第二个你使用IQueryable (没有泛型类型参数)。

您可以检查出两种完全不同的接口, 在这里和这里 。



Answer 3:

以下是此扩展方法:

public static class ListHelper
{
    public static IList ToList(this IQueryable query)
    {
        var genericToList = typeof(Enumerable).GetMethod("ToList")
            .MakeGenericMethod(new Type[] { query.ElementType });
        return (IList)genericToList.Invoke(null, new[] { query });
    }
}


文章来源: Where is the ToList() method? (IQueryable)