簡體   English   中英

在List <T>和IEnumerable <T>之間自由轉換

[英]Freely convert between List<T> and IEnumerable<T>

如何將List<MyObject>轉換為IEnumerable<MyObject>然后再返回?

我想這樣做是為了在List上運行一系列LINQ語句,例如Sort()

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

List<T>是一個IEnumerable<T> ,實際上,沒有必要將List<T> “轉換”為IEnumerable<T> 由於List<T>IEnumerable<T> ,因此您可以簡單地將List<T>分配給IEnumerable<T>類型的變量。

IEnumerable<T> ,並非每個IEnumerable<T>都是一個List<T> offcourse,那么你將不得不調用IEnumerable<T>ToList()成員方法。

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()

旁白:請注意,標准LINQ運算符(根據前面的示例)不會更改現有列表list.OrderBy(...).ToList()將基於重新排序的序列創建新列表。 但是,創建一個允許使用帶有List<T>.Sort lambdas的擴展方法非常簡單:

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相同的方式更新現有列表。

List<T>轉換為IEnumerable<T>

List<T>實現IEnumerable<T> (以及許多其他如IList<T>, ICollection<T> ),因此不需要將List轉換回IEnumerable,因為它已經是IEnumerable<T>

例:

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;

您還可以使用Enumerable.AsEnumerable()方法

IEnumerable<Person> iPersonList = people.AsEnumerable();

IEnumerable<T>轉換為List<T>

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

這在實體框架中很有用。

為了防止內存重復,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。 這在大多數情況下是正確的,至少有兩個原因:這有助於防止影響其他區域的一個區域的變化(松散耦合),並且它非常易讀,因為我們不應該設計具有編譯器問題的代碼。

但是在某些情況下,例如處於緊密循環或在嵌入式或低內存系統上工作,應考慮編譯器的考慮因素。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM