繁体   English   中英

C# - AsEnumerable 示例

[英]C# - AsEnumerable Example

AsEnumerable 的具体用途是什么? 它会将不可枚举的集合更改为可枚举的集合吗?请给我一个简单的例子。

从MSDN文档的“备注”部分

除了将源代码的编译时类型从实现IEnumerable<T>的类型更改为IEnumerable<T>本身之外, AsEnumerable<TSource>方法没有任何效果。

AsEnumerable<TSource>可用于在序列实现IEnumerable<T>时选择查询实现,但也可以使用一组不同的公共查询方法。 例如,给定一个实现IEnumerable<T>并具有自己的方法(如WhereSelectSelectMany的泛型类Table ,对Where调用将调用Table的public Where方法。 表示数据库表的Table类型可以具有Where方法,该方法将谓词参数作为表达式树并将树转换为SQL以进行远程执行。 如果不需要远程执行,例如因为谓词调用本地方法,则可以使用AsEnumerable<TSource>方法隐藏自定义方法,而是使标准查询运算符可用。

如果你看看反射器:

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

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

没有人出于某种原因提到过这个,但是观察something.AsEnumerable() (IEnumerable<TSomething>) something something.AsEnumerable()等同于(IEnumerable<TSomething>) something 不同之处在于演员要求明确指定元素的类型,这当然是不方便的。 对我来说,这是使用AsEnumerable()而不是AsEnumerable()主要原因。

AsEnumerable()将数组(或列表或集合)转换为集合的IEnumerable <T>。

有关更多信息,请参见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.
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.
        */
    }

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

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

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

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

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

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

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

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

第二个是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));

两者都没有流畅。

Enumerable.AsEnumerable 方法可用于隐藏类型的标准查询运算符的自定义实现

考虑以下示例。 我们有一个名为MyList的自定义List

public class MyList<T> : List<T>
{
    public string Where()
    {
        return $"This is the first element {this[0]}";
    }
}

MyList有一个名为Where的方法,它与Enumerable.Where()完全相同的名称。 当我使用它时,实际上我是在调用我的Where版本,而不是Enumerable的版本

MyList<int> list = new MyList<int>();

list.Add(4);
list.Add(2);
list.Add(7);

string result = list.Where();

// the result is "This is the first element 4"

现在如何使用EnumerableWhere版本找到小于 5 的元素?

答案是:使用AsEnumerable()方法然后调用Where

IEnumerable<int> result = list.AsEnumerable().Where(e => e < 5);

这次结果包含小于 5 的元素列表

暂无
暂无

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

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