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

Eri*_*bes 63 c# linq ienumerable

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

例:

List<string> strings = new List<string>() { "test", "test2", "test3" };
IEnumerable<string> stringsEnum1 = strings.AsEnumerable();
IEnumerable<string> stringsEnum2 = (IEnumerable<string>)strings;
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,stringsEnum1并且stringsEnum2是等价的.扩展方法有什么意义?

编辑:作为推论,为什么.AsQueryable()在施法时有一种方法IQueryable<T>是等价的?

jas*_*son 84

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

Table.AsEnumerable().Where(somePredicate)
Run Code Online (Sandbox Code Playgroud)

比...更具可读性

((IEnumerable<TableObject>)Table).Where(somePredicate).
Run Code Online (Sandbox Code Playgroud)

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

Table.Where(somePredicate)
     .Select(someProjection)
     .AsEnumerable()
     .SomethingElse()
Run Code Online (Sandbox Code Playgroud)

((IEnumerable<SomeProjectionType>)Table.Where(somePredicate)
                                       .Select(someProjection))
                                       .SomethingElse()
Run Code Online (Sandbox Code Playgroud)

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

因此列举了

Table.Where(somePredicate)
Run Code Online (Sandbox Code Playgroud)

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

Table.AsEnumerable().Where(somePredicate)
Run Code Online (Sandbox Code Playgroud)

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

这是要点AsEnumerable:允许您隐藏IEnumerable方法的特定实现,而是使用标准实现.

  • 我已经得到了它 - 它们在技术上是等价的,但由于匿名类型,AsEnumerable更有能力:你不能转换为IEnumerable的匿名类型,但AsEnumerable可以. (28认同)
  • 我发现`Table.AsEnumerable().Where(somePredicate)`比`((IEnumerable <TableObject>)表更易读.表(.)(somePredicate)`. (6认同)
  • 的确如此-但是不会转换为`IEnumerable &lt;T&gt;`提供相同的结果吗? (2认同)
  • 这是非常好的一点。我确实认为这是有好处的。我认为重点是可读性。 (2认同)

Eri*_*bes 16

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

例:

// 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)
              };
Run Code Online (Sandbox Code Playgroud)

显然,这里的原因是我们希望使用Linq to SQL之类的东西将一些记录下拉成匿名类型,然后使用Linq to客户端上的对象执行一些自定义逻辑(通过Linq to SQL无法实现) - 侧.

铸造IEnumerable<_anon>是不可能的,所以.AsEnumerable()是唯一的方法.

谢谢所有回答的人帮我拼凑这个.=)