ฉันสามารถแปลงList<MyObject>
ไปยังIEnumerable<MyObject>
และจากนั้นกลับมาอีกครั้ง?
ฉันต้องการทำสิ่งนี้เพื่อเรียกใช้ชุดคำสั่ง LINQ ในรายการเช่น Sort()
ฉันสามารถแปลงList<MyObject>
ไปยังIEnumerable<MyObject>
และจากนั้นกลับมาอีกครั้ง?
ฉันต้องการทำสิ่งนี้เพื่อเรียกใช้ชุดคำสั่ง LINQ ในรายการเช่น Sort()
คำตอบ:
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myEnumerable.ToList();
using System.Linq;
จะไม่สามารถ ToList ()
A List<T>
คือ an IEnumerable<T>
จริงๆแล้วไม่จำเป็นต้อง 'แปลง' a List<T>
เป็นIEnumerable<T>
ไฟล์. เนื่องจาก a List<T>
คือ an IEnumerable<T>
คุณสามารถกำหนด a List<T>
ให้กับตัวแปรประเภทIEnumerable<T>
ได้
ในทางกลับกันไม่ใช่ว่าทุกคนIEnumerable<T>
จะเป็นList<T>
offcourse ดังนั้นคุณจะต้องเรียกToList()
เมธอดสมาชิกของIEnumerable<T>
.
A List<T>
อยู่แล้วIEnumerable<T>
ดังนั้นคุณสามารถเรียกใช้คำสั่ง LINQ ได้โดยตรงบนList<T>
ตัวแปรของคุณ
หากคุณไม่เห็นวิธีการขยาย LINQ อย่างที่OrderBy()
ฉันคาดเดาว่าเป็นเพราะคุณไม่มีusing System.Linq
คำสั่งในไฟล์ต้นฉบับของคุณ
คุณจำเป็นต้องแปลงผลลัพธ์นิพจน์ LINQ กลับเป็นList<T>
อย่างชัดเจนแม้ว่า:
List<Customer> list = ...
list = list.OrderBy(customer => customer.Name).ToList()
นอกเหนือ: โปรดทราบว่าตัวดำเนินการ LINQ มาตรฐาน (ตามตัวอย่างก่อนหน้านี้) จะไม่เปลี่ยนแปลงรายการที่มีอยู่ - list.OrderBy(...).ToList()
จะสร้างรายการใหม่ตามลำดับที่เรียงใหม่ อย่างไรก็ตามมันค่อนข้างง่ายในการสร้างวิธีการขยายที่ช่วยให้คุณใช้ lambdas กับ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
มักจะทำ
ToList
- ฉันจะชี้แจง
List<T>
เป็นIEnumerable<T>
List<T>
การดำเนินการIEnumerable<T>
(และอื่น ๆ อีกมากมายเช่นIList<T>, ICollection<T>
) ดังนั้นจึงไม่จำเป็นต้องแปลงรายการกลับเป็น 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();
นี้จะเป็นประโยชน์ในEntity Framework
เพื่อป้องกันการทำซ้ำในหน่วยความจำ resharper ขอแนะนำสิ่งนี้:
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myList as List<string>() ?? myEnumerable.ToList();
.oList () ส่งคืนรายการที่ไม่เปลี่ยนรูปใหม่ ดังนั้นการเปลี่ยนแปลง listAgain จึงไม่มีผลกับ myList ในคำตอบของ @Tamas Czinege สิ่งนี้ถูกต้องในกรณีส่วนใหญ่ด้วยเหตุผลอย่างน้อยสองประการ: สิ่งนี้ช่วยป้องกันการเปลี่ยนแปลงในพื้นที่หนึ่งที่ส่งผลกระทบต่อพื้นที่อื่น ๆ (การมีเพศสัมพันธ์แบบหลวม) และสามารถอ่านได้มากเนื่องจากเราไม่ควรออกแบบโค้ดด้วยความกังวลเกี่ยวกับคอมไพเลอร์
แต่มีบางกรณีเช่นอยู่ในวง จำกัด หรือทำงานบนระบบหน่วยความจำฝังตัวหรือหน่วยความจำเหลือน้อยซึ่งควรคำนึงถึงคอมไพเลอร์ด้วย