首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么要使用.AsEnumerable()而不是强制转换为IEnumerable<T>?

为什么要使用.AsEnumerable()而不是强制转换为IEnumerable<T>?
EN

Stack Overflow用户
提问于 2010-01-06 23:10:57
回答 7查看 46.6K关注 0票数 67

.AsEnumerable()IEnumerable<T>上的一种扩展方法。此方法将调用它的可枚举对象转换为IEnumerable<T>的实例。但是,由于对象必须实现IEnumerable<T>才能应用于此扩展方法,因此转换为IEnumerable<T>很简单,只需转换为IEnumerable<T>即可。我的问题是,为什么会存在这种方法?

示例:

代码语言:javascript
复制
List<string> strings = new List<string>() { "test", "test2", "test3" };
IEnumerable<string> stringsEnum1 = strings.AsEnumerable();
IEnumerable<string> stringsEnum2 = (IEnumerable<string>)strings;

在上面的示例中,stringsEnum1stringsEnum2是等效的。扩展方法的意义是什么?

编辑:作为推论,为什么在转换为IQueryable<T>时会有.AsQueryable()方法?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2010-01-06 23:15:41

可读性是这里的主要问题。考虑一下这点

代码语言:javascript
复制
Table.AsEnumerable().Where(somePredicate)

的可读性远远高于

代码语言:javascript
复制
((IEnumerable<TableObject>)Table).Where(somePredicate).

或者想象一下,想要在SQL Server上执行查询的一部分,其余的在内存中执行:

代码语言:javascript
复制
Table.Where(somePredicate)
     .Select(someProjection)
     .AsEnumerable()
     .SomethingElse()

对比

代码语言:javascript
复制
((IEnumerable<SomeProjectionType>)Table.Where(somePredicate)
                                       .Select(someProjection))
                                       .SomethingElse()

现在,至于为什么这样的方法是有用的,想想LINQ to SQL DataContext中的Table的例子。由于Table是一个IQueryable,因此它实现了IEnumerable。当您在这样的Table上调用Where方法并枚举结果时,将执行最终导致在SQL Server上执行SQL语句的代码。AsEnumerable所做的是,不,我不想使用LINQ to SQL提供程序来执行Where,我想使用Where的LINQ to Objects实现。

因此枚举了

代码语言:javascript
复制
Table.Where(somePredicate)

导致在SQL Server上执行查询,而枚举

代码语言:javascript
复制
Table.AsEnumerable().Where(somePredicate)

Table表示的表放入内存中,并在内存中(而不是在SQL Server上!)执行Where功能。

这就是AsEnumerable的意义所在:允许您隐藏IEnumerable方法的特定实现,而使用标准实现。

票数 90
EN

Stack Overflow用户

发布于 2010-01-06 23:46:09

除了可读性之外,我还想到了一个与查询实现相关的原因:在通过另一个Linq提供程序返回的匿名类型上使用Linq to对象。您不能强制转换为匿名类型(或匿名类型的集合),但可以使用.AsEnumerable()为您执行强制转换。

示例:

代码语言:javascript
复制
// Get an IQueryable of anonymous types.
var query = from p in db.PeopleTable /* Assume Linq to SQL */
            select new { Name = p.Name, Age = p.Age };

// Execute the query and pull the results into an IEnumerable of anonymous types
var @enum = query.AsEnumerable();

// Use Linq to Objects methods to further refine.
var refined = from p in @enum
              select new
              {
                  Name = GetPrettyName(p.Name),
                  DOB = CalculateDOB(p.Age, DateTime.Now)
              };

很明显,这里的原因是我们想要使用像Linq to SQL这样的东西将一些记录拉入匿名类型,然后在客户端使用Linq to对象执行一些自定义逻辑(通过Linq to SQL是不可能的)。

转换为IEnumerable<_anon>是不可能的,所以.AsEnumerable()是唯一的方法。

感谢每一位回复帮助我拼凑这些东西的人。=)

票数 16
EN

Stack Overflow用户

发布于 2017-01-06 17:33:03

因为我正在读C# 6.0 in a Nutshell这本书。下面是本书中的AsEnumerable示例。

其目的是将IQueryable<T>序列强制转换为IEnumerable<T>,强制后续查询操作符绑定到可枚举操作符,而不是可查询操作符。这会导致查询的其余部分在本地执行。

为了进行说明,假设我们在SQL Server中有一个MedicalArticles表,并且希望使用LINQ To SQL或EF来检索摘要少于100个单词的所有关于流感的文章。对于后一个谓词,我们需要一个正则表达式:

代码语言:javascript
复制
Regex wordCounter = new Regex (@"\b(\w|[-'])+\b");

var query = dataContext.MedicalArticles
            .Where (article => article.Topic == "influenza" &&
            wordCounter.Matches (article.Abstract).Count < 100);

问题是SQL Server不支持正则表达式,因此LINQ- to -db提供程序将抛出异常,抱怨查询无法转换为SQL。我们可以通过两个步骤进行查询来解决这个问题:首先通过LINQ to SQL查询检索所有关于流感的文章,然后在本地过滤少于100字的摘要:

代码语言:javascript
复制
Regex wordCounter = new Regex (@"\b(\w|[-'])+\b");

IEnumerable<MedicalArticle> sqlQuery = dataContext.MedicalArticles
    .Where (article => article.Topic == "influenza");

IEnumerable<MedicalArticle> localQuery = sqlQuery
    .Where (article => wordCounter.Matches (article.Abstract).Count < 100);

使用AsEnumerable,我们可以在单个查询中完成相同的操作:

代码语言:javascript
复制
var query = dataContext.MedicalArticles
      .Where (article => article.Topic == "influenza")
      .AsEnumerable()
      .Where (article => wordCounter.Matches (article.Abstract).Count < 100);

调用AsEnumerable的另一种方法是调用ToArray或ToList。 AsEnumerable的优势在于它不会强制执行立即查询,也不会创建任何存储结构。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2013846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档