2009-01-23 28 views
99

如何将List<MyObject>转换为IEnumerable<MyObject>然后再返回?在列表<T>和IEnumerable之间自由转换<T>

我想这样做是为了在列表上运行一系列的LINQ语句, G。 Sort()

+0

这是在这个问题中涵盖http://stackoverflow.com/questions/31708/how-can-i-convert-ienumerablet-to-listt-in-c – John 2010-03-04 15:59:25

回答

141
List<string> myList = new List<string>(); 
IEnumerable<string> myEnumerable = myList; 
List<string> listAgain = myEnumerable.ToList(); 
+29

但要注意,myEnumarable是相同的对象实例myList,但listAgain与myEnumerable不是同一个对象实例。根据您想要做什么以及myEnumerable是什么,“列表 listAgain = myEnumerable as List ;”可能会更好。 – ChrisW 2009-01-23 12:12:54

+1

Chrisw:哦,是的,你当然是对的,但IEnumerable接口是不可变的,所以它不会在这个方向上引发问题,并且当你有一个可以处理类型安全的函数时,只会觉得*脏*。 – 2009-01-23 12:17:19

+1

你也可以使用原始的myList对象。 (我想我真的不知道这个问题) – sth 2009-01-23 12:27:51

5

旁白:需要注意的是标准的LINQ运营商(按刚才的例子),不改变现有的名单 - list.OrderBy(...).ToList()将创建一个基于重新排序的序列中的新名单。这是很容易,然而,创建一个扩展方法,使您可以使用lambda表达式与List<T>.Sort

static void Sort<TSource, TValue>(this List<TSource> list, 
    Func<TSource, TValue> selector) 
{ 
    var comparer = Comparer<TValue>.Default; 
    list.Sort((x,y) => comparer.Compare(selector(x), selector(y))); 
} 

static void SortDescending<TSource, TValue>(this List<TSource> list, 
    Func<TSource, TValue> selector) 
{ 
    var comparer = Comparer<TValue>.Default; 
    list.Sort((x,y) => comparer.Compare(selector(y), selector(x))); 
} 

然后你可以使用:

list.Sort(x=>x.SomeProp); // etc 

这将更新一样现有列表List<T>.Sort通常会这样做。

21

A List<T>IEnumerable<T>,所以实际上,不需要将List<T>“转换”为IEnumerable<T>。 由于List<T>IEnumerable<T>,您可以简单地将List<T>分配给类型为IEnumerable<T>的变量。

周围的其他方式,不是每个IEnumerable<T>List<T> offcourse,所以那么你就必须调用IEnumerable<T>ToList()成员方法。

9

A List<T>已经是IEnumerable<T>,所以你可以直接在你的List<T>变量上运行LINQ语句。

如果你看不到像OrderBy()这样的LINQ扩展方法,我猜这是因为你的源文件中没有using System.Linq指令。

你需要的LINQ表达式的结果转换回List<T>明确,虽然:

List<Customer> list = ... 
list = list.OrderBy(customer => customer.Name).ToList() 
0

为了防止在存储器备份,ReSharper的是在暗示这样的:

List<string> myList = new List<string>(); 
IEnumerable<string> myEnumerable = myList; 
List<string> listAgain = myList as List<string>() ?? myEnumerable.ToList(); 

.ToList()返回一个新的不可变列表。因此,对ListAgain的更改不会影响@Tamas Czinege答案中的myList。在大多数情况下,这是正确的,至少有两个原因:这有助于防止影响其他区域的一个区域发生变化(松散耦合),并且它非常易读,因为我们不应该用编译器问题来设计代码。

但是有些情况下,如处于一个紧密的循环中,或者在嵌入式或低内存系统上工作,需要考虑编译器的考虑因素。

0

List(T)类实现了IEnumerable(T)(以及很多其他的如IList(T),ICollection(T),IEnumerable(T)),因此不需要将List转换回IEnumerable。

public class Person 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

Person person1 = new Person() { Id = 1, Name = "Person 1" }; 
Person person2 = new Person() { Id = 2, Name = "Person 2" }; 
Person person3 = new Person() { Id = 3, Name = "Person 3" }; 

List<Person> people = new List<Person>() { person1, person2, person3 }; 

//Converting to an IEnumerable 
IEnumerable<Person> IEnumerableList = people; 

但是从IEnumerable的转换列表是一个有效的方案

IEnumerable<Person> OriginallyIEnumerable = new List<Person>() { person1, person2 }; 
List<Person> convertToList = OriginallyIEnumerable.ToList(); 

这是Entity Framework有用。

相关问题