C# - AsEnumerable示例

时间:2009-11-19 15:01:18

标签: c# enumeration

AsEnumerable的确切用途是什么?它会将非可枚举集合更改为可枚举 收藏?。请给我一个简单的例子。

9 个答案:

答案 0 :(得分:8)

From the "Remarks" section of the MSDN documentation

  

AsEnumerable<TSource>方法无效   除了改变编译时   类型为 source 的类型   实现IEnumerable<T>到   IEnumerable<T>本身。

     

AsEnumerable<TSource>可用于选择   查询实现之间的时间   sequence实现IEnumerable<T>但也有不同的集合   可用的公共查询方法。对于   例如,给定泛型类Table   实现IEnumerable<T>并具有自己的方法   作为WhereSelectSelectMany,a   拨打Where会调用公众   Where的{​​{1}}方法。 Table类型   表示数据库表可以   有一个Table方法,需要   谓词参数作为表达式   树并将树转换为SQL for   远程执行。如果远程执行   是不希望的,例如因为   谓词调用本地方法,   Where   方法可用于隐藏自定义   方法,而不是制定标准   查询运算符可用。

答案 1 :(得分:6)

如果你看看反射器:

public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source)
{
    return source;
}

它基本上只是向下转换实现IEnumerable的东西。

答案 2 :(得分:3)

由于某种原因,没有人提到这一点,但请注意something.AsEnumerable()等同于(IEnumerable<TSomething>) something。不同之处在于演员要求明确指定元素的类型,这当然是不方便的。对我来说,这是使用AsEnumerable()代替演员的主要原因。

答案 3 :(得分:1)

AsEnumerable()将数组(或列表或集合)转换为IEnumerable&lt; T&gt;该系列。

有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/bb335435.aspx

从上面的文章:

The AsEnumerable<TSource>(IEnumerable<TSource>) method has no 
effect other than to change the compile-time type of source from a type 
that implements IEnumerable<T> to IEnumerable<T> itself.

答案 4 :(得分:0)

AsEnumerable只能用于可枚举的集合。它只是将集合的类型更改为IEnumerable<T>,以便更轻松地访问IEnumerable扩展。

答案 5 :(得分:0)

不,它不会将不可枚举的集合更改为可枚举的集合。它将集合作为IEnumerable返回给您是什么,以便您可以将其用作可枚举的。这样,您就可以将该对象与IEnumerable扩展一起使用,并将其视为这样。

答案 6 :(得分:0)

在阅读答案之后,我猜你仍然缺少一个实际的例子。

我使用它来使我能够在数据表上使用linq

var mySelect = from table in myDataSet.Tables[0].AsEnumerable()
            where table["myColumn"].ToString() == "Some text"
            select table;

答案 7 :(得分:0)

以下示例代码可以说明LukeH的正确解释。

IEnumerable<Order> orderQuery = dataContext.Orders
  .Where(o => o.Customer.Name == "Bob")
  .AsEnumerable()
  .Where(o => MyFancyFilterMethod(o, MyFancyObject));

第一个是Queryable.Where,它被翻译成sql并在数据库中运行(o.Customer没有加载到内存中)。

第二个Where Enumerable.Where,它使用我不想发送到数据库的实例调用内存中方法。

如果没有AsEnumerable方法,我必须这样写:

IEnumerable<Order> orderQuery =
  ((IEnumerable<Order>)
    (dataContext.Orders.Where(o => o.Customer.Name == "Bob")))
  .Where(o => MyFancyFilterMethod(o, MyFancyObject));

或者

IEnumerable<Order> orderQuery =
  Enumerable.Where(
    dataContext.Orders.Where(o => o.Customer.Name == "Bob"),
    (o => MyFancyFilterMethod(o, MyFancyObject));

两者都没有流畅。

答案 8 :(得分:0)

static void Main()
    {
        /* 
        "AsEnumerable" purpose is to cast an IQueryable<T> sequence to IEnumerable<T>, 
        forcing the remainder of the query to execute locally instead of on database as below example so it can hurt performance.  (bind  Enumerable operators instead of Queryable). 

        In below example we have cars table in SQL Server and are going to filter red cars and filter equipment with some regex:
        */
        Regex wordCounter = new Regex(@"\w");
        var query = dataContext.Cars.Where(car=> article.Color == "red" && wordCounter.Matches(car.Equipment).Count < 10);

        /* 
        SQL Server doesn’t support regular expressions  therefore the LINQ-to-db  providers  will  throw  an  exception: query  cannot  be translated to SQL.

        TO solve this firstly we can get all cars with red color using a LINQ to SQL query, 
        and secondly filtering locally for Equipment of less than 10 words:
        */

        Regex wordCounter = new Regex(@"\w");

        IEnumerable<Car> sqlQuery = dataContext.Cars
          .Where(car => car.Color == "red");
        IEnumerable<Car> localQuery = sqlQuery
          .Where(car => wordCounter.Matches(car.Equipment).Count < 10);

        /*
        Because sqlQuery is of type IEnumerable<Car>, the second query binds  to the local query operators,
        therefore that part of the filtering is run on the client.

        With AsEnumerable, we can do the same in a single query:

         */
        Regex wordCounter = new Regex(@"\w"); 
        var query = dataContext.Cars
          .Where(car => car.Color == "red")
          .AsEnumerable()
          .Where(car => wordCounter.Matches(car.Equipment).Count < 10);

        /*
        An alternative to calling AsEnumerable is ToArray or ToList.
        */
    }