ToList()方法在哪里?(IQueryable的)

mar*_*nda 13 .net c# linq extension-methods

如果我试试这个,它会起作用:

var query = myContextObject.Users.Where(u=>u.Name == "John");
query.ToList();
Run Code Online (Sandbox Code Playgroud)

我可以打电话ToList和许多其他扩展方法.

但如果我试试这个:

public List ConvertQueryToList(IQueryable query)
{
    return query.ToList();
}
Run Code Online (Sandbox Code Playgroud)

ToList将无法访问,我猜这是因为ToList是一种扩展方法,但那么ToList第一个例子中是如何附加的呢?是否可以ToList在第二种情况下访问?

Ree*_*sey 18

你需要把它写成:

public List<T> ConvertQueryToList<T>(IQueryable<T> query)
{
    return query.ToList();
}
Run Code Online (Sandbox Code Playgroud)

这将导致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();
}
Run Code Online (Sandbox Code Playgroud)

这将需要调用如下:

var results = ConvertQueryToList<SomeType>(queryable);
Run Code Online (Sandbox Code Playgroud)

或者,如果你想保留这种非通用的(我不推荐),那么你可以使用:

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


Jon*_*ton 10

第一个示例返回一个IQueryable<T>,而在第二个示例中返回IQueryable(没有Generic Type参数).

您可以在此处此处查看两个完全不同的界面.

  • 我见过`IQueryable`(非泛型)的一个地方是Linq-To-SQL的动态linq提供程序.由于动态linq提供程序将字符串作为参数,因此它没有可用的类型. (2认同)

Ham*_*jam 5

这是对此的扩展方法:

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 });
    }
}
Run Code Online (Sandbox Code Playgroud)