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

时间:2012-09-03 22:55:15

标签: c# .net linq extension-methods

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

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

我可以调用ToList和许多其他扩展方法。

但如果我试试这个:

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

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

4 个答案:

答案 0 :(得分:16)

你需要把它写成:

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

这会导致IQueryable<T>返回相应的List<T>,因为Enumerable.ToList()方法需要IEnumerable<T>作为输入(也适用于IQueryable<T>,作为IQueryable<T> inherits 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;
}

答案 1 :(得分:9)

您的第一个示例返回IQueryable<T>,而在第二个示例中,您使用的是IQueryable(没有Generic Type参数)。

您可以查看两个完全不同的界面herehere

答案 2 :(得分: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 });
    }
}

答案 3 :(得分:-1)

对于使用IQueryable <>的情况,这是一种通用扩展方法。 当然,这不是绝对安全的,因为类型可能错误并且强制转换可能失败。因此,如果使用该方法,请小心。

using System.Collections.Generic;
  
namespace System.Linq
{
    public static class Extensions
    {
        public static List<T> ToList<T>(this IQueryable queriable)
        {
            return ((IQueryable<T>)queriable).ToList();
        }
    }
}