Ienumerable trong c# là gì, ienumerable interface (system

     

Khi áp dụng C# để thiết kế, chúng ta cũng có thể đang bắt gặp từ bỏ khóa yield tương đối nhiều lần tuy nhiên khôn xiết ít khi họ biết được nó là gì với bao gồm tác dụng nlỗi nào? Hôm ni, bản thân đã share với các bạn hầu như phát âm biết của chính mình về yield, siêu mong muốn hồ hết share này đang bổ ích mang lại chúng ta trên con phố thành master C# nhé.

Bạn đang xem: Ienumerable trong c# là gì, ienumerable interface (system

Trước Lúc nói về từ bỏ khóa yield, chúng ta cùng kể lại về IEnumerable.

1. IEnumerable là gì

IEnumerable là một trong những danh sách bao gồm các ở trong tính sau:- Danh sách chỉ gọi, không được phép thêm/giảm phần tử- Chỉ coi ngó một chiều từ đầu cho tới cuối list. Sử dụng foreach nhằm tiến hành duyệt

Các chúng ta có thể tìm hiểu thêm trên bài viết "IEnumerable và IEnumerator vào C#" trên phía trên.

2. Yield là gì

Yield là từ khóa vẫn thông tin mang đến trình biên dịch hiểu được cách tiến hành, toán tử, get mà nó xuất hiện thêm đang là 1 trong những kăn năn lặp. Trình biên dịch vẫn tự động ra đời một class implement trường đoản cú IEnumerable, IEnumerator để miêu tả kăn năn lặp đó.

Chúng ta hãy xét ví dụ sau:

class Program private static IEnumerable Ints() for (var i = 0; i Sau Khi biên dịch lịch sự tệp tin exe pháo với dịch ngược lại tệp tin exe đó, bọn họ chiếm được class nhỏng sau:

internal class Program // Methods private static IEnumerable Ints() this.5__1 = 0; while (this.5__1 5__1; int num2 = this.5__1; this.5__1 = numét vuông + 1; private static void Main(string<> args) foreach (int num in Ints()) Console.WriteLine(num); Console.ReadKey(); // Nested Types private sealed class d__1 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator // Fields private int 1__state; private int 2__current; private int l__initialThreadId; private int 5__1; // Methods public d__1(int 1__state) this.1__state = 1__state; this.l__initialThreadId = Environment.CurrentManagedThreadId; private bool MoveNext() switch (this.1__state) case 0: this.1__state = -1; this.5__1 = 0; while (this.5__1 2__current = this.5__1; this.1__state = 1; return true; Label_003F: this.1__state = -1; int numét vuông = this.5__1; this.5__1 = num2 + 1; return false; case 1: goto lớn Label_003F; return false; IEnumerator IEnumerable.GetEnumerator() if ((this.1__state == -2) && (this.l__initialThreadId == Environment.CurrentManagedThreadId)) this.1__state = 0; return this; return new Program.d__1(0); IEnumerator IEnumerable.GetEnumerator() => this.System.Collections.Generic.IEnumerable.GetEnumerator(); void IEnumerator.Reset() throw new NotSupportedException(); void IDisposable.Dispose() // Properties int IEnumerator.Current => this.2__current; object IEnumerator.Current => this.2__current; Giờ các bạn lưu ý:HàmIEnumerable Ints() có xuất hiện trường đoản cú khóa yield với được gán thêm nằm trong tínhIteratorStateMachine(typeof(d__1)), cùng với thuộc tính này trình biên dịch sẽ chứng thực hàm trên là 1 trong kăn năn lặp (hoặc hoàn toàn có thể Hotline là state machine).Classd__1 được trình biên dịch hiện ra, implement trường đoản cú IEnumerable, IEnumerator nhằm triển khai cho khối lặp bên trên.

3. Cách sử dụng

Từ khóa yield được áp dụng vào 2 trường hợp nlỗi sau:

yield return ;yield break;Lưu ý:- Đối cùng với hàm hoặc get thực hiện trường đoản cú khóa yield cần phải trả về vẻ bên ngoài tài liệu là IEnumerable, IEnumerable, IEnumerator hoặc IEnumerator.- Sử dụng trong vòng lặp tất cả ĐK (nếu như không có điều kiện thì trả luôn luôn danh sách buộc phải ko kể trường vừa lòng này).- Lưu tinh thần của lần lặp trước.lấy một ví dụ họ tất cả list bao gồm 10 phần tử từ 0 cho 9 như sau:

private static List MyList = new List 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ;3.1. yield returnNếu là hàm không thực hiện yield thì lúc return, lịch trình sẽ thoát ra khỏi hàm kia.Nếu là hàm áp dụng yield return thì lịch trình đang trả về tài liệu cùng trở lại vòng lặp nhằm tiến hành vòng lặp tiếp sau.Chúng ta coi ví dụ liệt kê các phần tử có mức giá trị to hơn 3 bởi 2 cách nhỏng sau:

class Program private static List MyList = new List 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ; private static IEnumerable NoneYield() var d = new List(); foreach (var thành công in MyList) if (công trình > 3) d.Add(item); return d; private static IEnumerable UseYield() foreach (var công trình in MyList) if (cửa nhà > 3) yield return item; static void Main(string<> args) Console.WriteLine("None Yield"); foreach (var item in NoneYield()) Console.WriteLine(item); Console.WriteLine("Yield"); foreach (var chiến thắng in UseYield()) Console.WriteLine(item); Console.ReadKey(); Kết quả đã nhỏng sau:

*
Nếu không sử dụng yield, nhằm trả về list như trên, họ đề xuất tạo ra một list tạm để giữ số đông thành phần thỏa mãn nhu cầu ĐK, sau thời điểm lưu giữ hết phần đa phần tử kia mới tiến hành return.Nếu áp dụng yield thì sau thời điểm yield return, lịch trình tiến hành tiếp vòng foreach tiếp theo.

3.2. yield break

Nếu vòng lặp sử dụng break, khi gặp lệnh break, lịch trình chỉ thoát khỏi vòng lặp, đều dòng phía đằng sau cùng ngoài vòng lặp vẫn được tiến hành.Nếu vòng lặp áp dụng yield break, công tác sẽ thoát ra khỏi hàm cơ mà ko thực hiện các lệnh phía dưới.Chúng ta xét bài toán: liệt kê các phần tử không giống 3 (Lúc gặp gỡ quý hiếm 3 thì dừng):

class Program private static List MyList = new List 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ; private static IEnumerable NoneYield() var d = new List(); foreach (var thành tựu in MyList) if (cửa nhà != 3) d.Add(item); else break; Console.WriteLine("Done"); // Sử dụng dòng này để sáng tỏ return d; private static IEnumerable UseYield() foreach (var thắng lợi in MyList) if (nhà cửa != 3) yield return item; else yield break; Console.WriteLine("Done"); // Sử dụng chiếc này nhằm rành mạch static void Main(string<> args) Console.WriteLine("None Yield"); foreach (var nhà cửa in NoneYield()) Console.WriteLine(item); Console.WriteLine("=============================================="); Console.WriteLine("Yield"); foreach (var cửa nhà in UseYield()) Console.WriteLine(item); Console.ReadKey(); Và hiệu quả đã nhỏng sau:

*
Lúc thực hiện break thì mở ra mẫu chữ "Done", còn yield break thì ko.

4. Một số lưu ý Khi sử dụng

4.1. khi sử dụng yield, họ nên vâng lệnh một số trong những từng trải sau:

Không sử dụng yield trong khối lệnh có từ bỏ khóa unsafe với trong hàm ẩn danh.

Xem thêm: Cách Làm Món Bạch Tuộc Nhúng Giấm Của Thế Vy, Bạch Tuộc Nhúng Giấm Giòn Ngon

Không sử dụng trường đoản cú khóa ref hoặc out kèm theo cùng với tđắm say số của hàm khi bên trong hàm thực hiện yield.yield return chỉ được sử dụng vào try catch có finally.yield break được sử dụng vào try catch không có finally.Chỉ phải sử dụng yield trong những trường hợp điều kiện trả về không quá phức tạp. Bản chất của việc sử dụng yield là có mặt class nhằm triển khai kân hận lặp. Trong kân hận lặp này còn có sử dụng đoạn mã nhằm kiểm soát điều kiện. Nếu bài toán chất vấn này vượt phức tạp sẽ ảnh hưởng trực tiếp tới hiệu năng của áp dụng.4.2. So sánh vận tốc giữa return và yield return

Chúng ta hãy coi ví dụ sau: trả về danh sách1.000.000 thành phần thực hiện 2 phương pháp là không áp dụng yield và bao gồm sử dụng yield

class Program { private static IEnumerable NoneYield() { var d = new List(); for (var i = 0; i UseYield() { for (var i = 0; i Chúng ta hãy coi kết quả:

*
quý khách hãy thực hiện chạy các lần giúp xem các công dụng khác biệt. Trung bình bọn họ vẫn thu được là vận tốc cách xử lý của hàm tất cả yield vội tối thiểu 10 lần. Một số lượng thật kinh khủng.

4.2. yield return bảo quản trạng thái của lần lặp trước

Chúng ta hãy xét ví dụ sau:

class Program { private static IEnumerable UseYield() { var total = 1; // 5 for (var i = 0; i Với đoạn code trên ai ai cũng suy nghĩ hiệu quả Lúc hiển thị ra screen là:

12345Nhưng khi chạy lịch trình sẽ đến kết quả là:

*

Ohh, chuyện gì xẩy ra vậy? Sao hiệu quả lại là 1 trong 2 4 7 11??? Chúng ta hãy đặt breakpoint trên loại 1, 3, 5, 6, 8 và demo debug coi công việc thực hiện:Cách 1: Thực hiện chạy lịch trình mang lại chiếc 1, tiếp tục thực hiện sẽ dancing mang đến chiếc 5 => thay đổi total được gán là một.Bước 2: Bắt đầu vòng lặp và gán i = 0, liên tiếp thực hiện mang đến cái 8 => đổi mới total = total + i => có mức giá trị 1 và yield return quý giá 1. Tiếp tục triển khai đã in 1 ra screen.Cách 3: Tiếp tục triển khai vòng lặp chiếc 1, liên tiếp tiến hành sẽ nhảy đến dòng 6 => với giá trị i = 1. Tiếp tục tiến hành total = total + i = 2 => yield return quý giá 2. Tiếp tục triển khai đang in 2 ra màn hình hiển thị.Bước 4: Tiếp tục tiến hành vòng lặp mẫu 1, tiếp tục triển khai đã khiêu vũ cho loại 6 => với cái giá trị i = 2. Tiếp tục thực hiện total = total + i = 4 => yield return giá trị 4. Tiếp tục triển khai đã in 4 ra màn hình.Từ bước này họ thấy rằng Việc gán phát triển thành total = 1 chỉ diễn ra 1 lần, quý hiếm này được tái thực hiện mang đến lần lặp tiếp sau. Vấn đề này lý giải mang lại vấn đề giữ giàng tâm trạng lúc thực hiện yield.Cách 5: quá trình được tái diễn cho đến i = 4.

Tạm kết

Trên trên đây tôi đã trình làng cùng với chúng ta về trường đoản cú khóa Yield, cách thức thực hiện và những xem xét Khi thao tác làm việc cùng với yield. Hi vọng bài viết hữu dụng với các bạn. Nếu bao gồm gì còn thắc mắc, hãy giữ lại phản hồi nhé.


Chuyên mục: Tin Tức