C# - AsEnumerable 示例

发布于 2024-08-12 00:26:38 字数 64 浏览 4 评论 0原文

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

What is the exact use of AsEnumerable? Will it change non-enumerable collection to enumerable
collection?.Please give me a simple example.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

掌心的温暖 2024-08-19 00:26:39

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"

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

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

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

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

The Enumerable.AsEnumerable method can be used to hide a type's custom implementation of a standard query operator

Consider the following example. we have a custom List called MyList

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

MyList has a method called Where which is Enumerable.Where() exact same name. when I use it, actually I am calling my version of Where, not Enumerable's version

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"

Now how can I find the elements which are less than 5 with the Enumerable's version of Where?

The answer is: Use AsEnumerable() method and then call Where

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

This time the result contains the list of elements that are less than 5

栀梦 2024-08-19 00:26:38

来自 MSDN 文档的“备注”部分

AsEnumerable 方法无效
除了改变编译时
来自以下类型的类型
实现 IEnumerable
IEnumerable 本身。

AsEnumerable 可以用来选择
当一个查询实现之间
序列实现了 IEnumerable 但也有不同的集合
可用的公共查询方法。为了
例如,给定一个通用类 Table
实现 IEnumerable 并拥有自己的方法,例如
作为 WhereSelectSelectMany
调用 Where 将调用 public
TableWhere 方法。 Table 类型
代表一个数据库表可以
有一个 Where 方法,它采用
作为表达式的谓词参数
树并将树转换为 SQL
远程执行。如果远程执行
不是所希望的,例如因为
谓词调用本地方法,
AsEnumerable
方法可用于隐藏自定义
方法,而不是制定标准
可用的查询运算符。

From the "Remarks" section of the MSDN documentation:

The AsEnumerable<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.

AsEnumerable<TSource> can be used to choose
between query implementations when a
sequence implements IEnumerable<T> but also has a different set
of public query methods available. For
example, given a generic class Table
that implements IEnumerable<T> and has its own methods such
as Where, Select, and SelectMany, a
call to Where would invoke the public
Where method of Table. A Table type
that represents a database table could
have a Where method that takes the
predicate argument as an expression
tree and converts the tree to SQL for
remote execution. If remote execution
is not desired, for example because
the predicate invokes a local method,
the AsEnumerable<TSource>
method can be used to hide the custom
methods and instead make the standard
query operators available.

不知在何时 2024-08-19 00:26:38

如果你看一下反射器:

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

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

If you take a look in reflector:

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

It basically does nothing more than down casting something that implements IEnumerable.

_畞蕅 2024-08-19 00:26:38

由于某种原因没有人提到这一点,但请注意 something.AsEnumerable() 相当于 (IEnumerable) some。不同之处在于强制转换需要显式指定元素的类型,这当然很不方便。对我来说,这是使用 AsEnumerable() 而不是强制转换的主要原因。

Nobody has mentioned this for some reason, but observe that something.AsEnumerable() is equivalent to (IEnumerable<TSomething>) something. The difference is that the cast requires the type of the elements to be specified explicitly, which is, of course, inconvenient. For me, that's the main reason to use AsEnumerable() instead of the cast.

七七 2024-08-19 00:26:38

AsEnumerable() 将数组(或列表或集合)转换为 IEnumerable类型。的集合。

请参阅 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.

AsEnumerable() converts an array (or list, or collection) into an IEnumerable<T> of the collection.

See http://msdn.microsoft.com/en-us/library/bb335435.aspx for more information.

From the above article:

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.
心欲静而疯不止 2024-08-19 00:26:38

阅读完答案后,我想您仍然缺少一个实际的例子。

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

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

After reading the answers, i guess you are still missing a practical example.

I use this to enable me to use linq on a datatable

var mySelect = from table in myDataSet.Tables[0].AsEnumerable()
            where table["myColumn"].ToString() == "Some text"
            select table;
花桑 2024-08-19 00:26:38

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

AsEnumerable can only be used on enumerable collections. It just changes the type of the collection to IEnumerable<T> to access more easily the IEnumerable extensions.

嗫嚅 2024-08-19 00:26:38

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

No it doesn't change a non-enumerable collection to an enumerable one. What is does it return the collection back to you as an IEnumerable so that you can use it as an enumerable. That way you can use the object in conjunction with IEnumerable extensions and be treated as such.

浅听莫相离 2024-08-19 00:26:38

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

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

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

两者都不能很好地运行。

Here's example code which may illustrate LukeH's correct explanation.

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

The first Where is Queryable.Where, which is translated into sql and run in the database (o.Customer is not loaded into memory).

The second Where is Enumerable.Where, which calls an in-memory method with an instance of something I don't want to send into the database.

Without the AsEnumerable method, I'd have to write it like this:

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

Or

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

Neither of which flow well at all.

再可℃爱ぅ一点好了 2024-08-19 00:26:38
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.
        */
    }
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.
        */
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文