IENUMERABLE C# LÀ GÌ

  -  
*

The Programmable Me


Tại phần 1, họ đã bàn về Functional programing (FP). Nếu nlỗi đó là lần đầu tiên các bạn xúc tiếp cùng với có mang này cùng cảm thấy nó khó hiểu thì cũng đừng sợ hãi, vị ai cũng tương đương bạn cả thôi. FP là 1 trong khái niệm đặc biệt và cũng là 1 trong những giữa những các đại lý nhằm Linq trong .NET được xuất bản. Vì vậy vào quá trình khám phá về Linq, bạn cũng sẽ làm rõ được rộng về FP.

Bạn đang xem: Ienumerable c# là gì

Trở lại cùng với Linq, thiên tài của C# hỗ trợ bạn làm việc với các tập phù hợp dữ liệu. Một trong những điều nhưng mà bản thân thấy các thiết kế viên mắc phải, đó là bài toán áp dụng Linq không nên quy biện pháp vị không nắm rõ bản chất của thư viện này. Chúng ta hãy thử chú ý vào định nghĩa của một method Linq điển hình nhỏng Where():

public static IEnumerable Where(this IEnumerable source,Func predicate)Nhỏng chúng ta thấy, method này được viết bên dưới dạng “extionsion method”. Đối với rất nhiều ai đắn đo, “extension method” là 1 trong tác dụng của C# nhằm mục đích giúp không ngừng mở rộng thêm những method mang lại class hoặc interface của người sử dụng bởi câu hỏi viết nó bên dưới dạng “static” tại 1 class không giống và áp dụng từ bỏ khóa “this”. Ở method bên trên, bạn có thể thấy rằng, interface được không ngừng mở rộng là IEnumerable. Nếu nhỏng các bạn đã phát âm kĩ phần trước, bạn sẽ biết rằng IEnumerable là interface đa số được Linq đào bới.Vì vậy nhằm hiểu rõ Linq thì bọn họ đề xuất nắm rõ về interface này.

IEnumerable cùng từ bỏ khóa yield return

IEnumerable được quan niệm vào System.Collection.Generics cùng là 1 trong những interface cực kì solo giản:

public interface IEnumerable IEnumerator GetEnumerator();Như chúng ta thấy, interface này chỉ có 1 method độc nhất vô nhị, GetEnumerator(), trả về một giá trị bao gồm dạng IEnumerator. IEnumerator được định nghĩa nhỏng sau:

public interface IEnumerator T Currentget; void Dispose(); bool MoveNext(); void Reset();Nhìn vào nhị interface trên, chắc hẳn các bạn cũng đoán được chân thành và ý nghĩa của bọn chúng. IEnumerator được cho phép chúng ta tiến hành gọi qua tất cả các quý giá vào một tập thích hợp. Hãy tưởng tượng ai đang hy vọng đọc cùng cách xử trí những dòng vào một bảng biểu, Khi bạn muốn gọi sang trọng tài liệu tiếp theo sau, bạn Gọi MoveNext() và gọi dữ liệu kia qua nằm trong tính Current. Lúc không còn dữ liệu nữa, MoveNext() sẽ trả về false. quý khách cũng hoàn toàn có thể gọi lại từ trên đầu bằng method Reset(), hoặc xóa khỏi cả tập thích hợp bởi Dispose()

IEnumerable là interface cơ bản độc nhất vô nhị thay mặt cho các thứ hạng tập đúng theo tài liệu trong C#, vì nó định nghĩa những tài năng cơ phiên bản duy nhất mà lại một tập vừa lòng đề xuất có: khả năng phát âm những thành phần một biện pháp theo thứ tự. Tất cả những class dùng làm chứa những tập phù hợp dữ liệu (Dictionary, Collection, ArrayList, List…) phần lớn thừa kế trường đoản cú interface này. IEnumerable cũng chính là interface chất nhận được chúng ta gọi tự khóa foreach , về cơ phiên bản đó là một vòng lặp nhưng auto Call MoveNext() cùng Current

Việc triển khai interface này tương đối đơn giản: Bạn có thể viết một linked-list nhằm cất tài liệu, vày linked-danh mục cũng được cho phép truy cập bộ phận một biện pháp lần lượt như vậy. Tuy nhiên vào C#, chúng ta gồm một bí quyết viết khác nhằm tự động hóa thành lập một kết cấu tài liệu thứ hạng IEnumerable, sẽ là bài toán thực hiện từ khóa yield return.

Cách cực tốt nhằm đọc được từ khóa này là dùng ví dụ:

IEnumerable generateString() yield return "one"; yield return "two"; yield return "three";Hàm generateString() ko Call bất kể class như thế nào thừa kế tự IEnumerable cả, mà dùng trường đoản cú khóa yield return. lúc một hàm sử dụng từ bỏ khóa này, hàm này được call là “Generator”. Khi hàm này chạm chán từ bỏ khóa “yield return“, nó vẫn xong chuyển động và gửi cực hiếm được yield kia vào chuỗi IEnumerable mà lại nó trả về. Hiện nay tại hàm call Generator đó, chúng ta cũng có thể gọi được ngay quý hiếm thứ nhất đó. lúc bạn có nhu cầu hiểu cực hiếm tiếp theo(bằng cách cần sử dụng foreach hoặc Điện thoại tư vấn MoveNext()), Generator đang tiếp tục chạy trường đoản cú địa chỉ yield return cũ cho đến từ khóa yield return tiếp sau. Các lần Hotline cực hiếm sau cũng diễn ra y giống như vậy. Đến Khi hàm này sẽ không chạm chán từ khóa yield return như thế nào nữa(hoặc Lúc nó chạm mặt tự khóa yield break) thì chuỗi IEnumerable trả về sẽ được hoàn chỉnh (đây là dịp mà lại MoveNext() trả về false)

Để dễ hiểu hơn, hãy tham khảo ví dụ sau đây.

Xem thêm: Bảo Thy Nấu Giả Cầy Ăn Với Rau Gì, Giả Cầy: Món Ngon Ngại Gì Tốn Kém

private static IEnumerable generateStrings() Console.WriteLine("yield one"); yield return "one"; Console.WriteLine("yield two"); yield return "two"; Console.WriteLine("yield three"); yield return "three";//codevar seq = generateStrings();foreach(string s in seq) Console.WriteLine($"loop i++"); Console.WriteLine(s);//output//yield one//loop 1//one//yield two//loop 2//two//yield three//loop 3//threeQuý khách hàng rất có thể thấy là hàm generateStrings() chỉ thường xuyên chạy Lúc vòng lặp foreach đưa thanh lịch quý giá tiếp theo của chuỗi IEnumerable. Đây là điểm tạo nên sự ưu thế độc nhất của IEnumerable: lazy evaluation, Tức là chỉ triển khai tính tân oán với trả về dữ liệu lúc được Điện thoại tư vấn. Ứng dụng của kĩ năng này là hết sức lớn: Hãy tưởng tượng bạn đang làm việc với cùng 1 nguồn dữ liệu khổng lồ, được điện thoại tư vấn xuất phát từ một nguồn tài liệu nào kia (database, network…). Quý khách hàng không thích điện thoại tư vấn toàn bộ những dữ liệu đó đồng thời, vì chưng nó quá to với quá mất thời hạn, mà cố kỉnh vào chính là Hotline chúng một giải pháp thứu tự. Khi bạn không muốn thường xuyên điện thoại tư vấn dữ liệu nữa, chúng ta cũng có thể dứt Generator này lại bởi những Điện thoại tư vấn yield break sinh hoạt phía bên trong hàm generator, hoặc điện thoại tư vấn Dispose() sinh sống IEnumerator của IEnumerable nhưng bạn nhận ra. Kiểu nhỏng sau:

IEnumerable getRecords() int i=0; while(true) Record record = ReadRecord(i++); yield return record; void Process() var records = getRecords(); var enumerator = records.GetEnumerator(); while(enumerator.MoveNext()) ProcessResult result = ProcessRecord(enumerator.Current); if (result == ProcessResult.Enough) enumerator.Dispose(); return; Nếu bạn thấy đa số điều trên là tương đối khó đọc thì cũng không có gì xứng đáng lo lắng cả, bởi generator là một trong tư tưởng tương đối khó khăn nắm bắt. Cách tốt nhất nhằm hiểu được nó là hãy mlàm việc Visual Studio lên và vứt thời gian đậm cá tính một chút ít.

Hàm Where vào Linq

Giờ thì dĩ nhiên bạn cũng thâu tóm được tương đối về IEnumerable rồi (trường hợp nhỏng không thì lời khuim của chính bản thân mình là nên dứt đọc và dành một ít thời gian để demo nghiệm). Chúng ta thử cần sử dụng điều đó để viết lại một hàm đơn giản độc nhất vô nhị trong Linq: Where (coi định nghĩa hàm này làm việc đầu bài)

Hàm Where về cơ phiên bản tất cả tác dụng giống như một filter(tương tự như câu “WHERE” trong sql). Nó khiến cho bạn tinh lọc ra mọi phần tử vào một tập thích hợp nhưng thỏa mãn nhu cầu một kinh nghiệm làm sao đó. Chúng ta hãy quay trở lại ví dụ với hàm generateStrings() sẽ viết làm việc trên(đã loại bỏ những đoạn Console.WriteLine()). Giả sử bạn có nhu cầu tinh lọc ra đông đảo string tất cả độ nhiều năm nhỏ dại hơn 4 (vào ngôi trường vừa lòng trên là “one” với “two”). Bạn trọn vẹn rất có thể viết như sau

public static class MyLinq{ public static IEnumerable Where(this IEnumerable source) { foreach(string s in source) { if(s.LengthĐiều này có nghĩa rằng chỉ hầu hết đoạn quý hiếm string nào có độ lâu năm nhỏ tuổi hơn 4 mới được hàm này tiếp nhận với gửi vào quý giá IEnumerable Áp sạc ra.

Xem thêm: Lỗi Http Error 403 Forbidden Là Lỗi Gì Và Làm Sao Để Sửa? Cách Sửa Lỗi Nhanh Và Hiệu Quả

Đoạn code bên trên vận động hoàn toàn đúng, quanh đó trừ câu hỏi nó không tồn tại tính tái thực hiện mang lại lắm: các bạn ko điều khiển được súc tích sàng lọc của hàm Where, và hàm Where ngày nay chỉ chuyển động với vẻ bên ngoài string nhưng thôi. quý khách hàng tất cả nhớ là vào phần trước, bọn họ tất cả kể tới câu hỏi C# cung cấp kiểu dáng tài liệu Func. Chúng ta hãy viết lại hàm Where nhằm tận dụng tối đa điều này:

public static class MyLinq public static IEnumerable Where(this IEnumerable source, Func predicate) foreach(T tòa tháp in source) if (predicate(item)) yield return s; //codevar source = generateStrings();var seq = source.Where(s=> s.Length Giờ thì hàm Where của họ vẫn tương đối kiểu như với hàm Where vào Linq rồi. Nó được cho phép bạn gọi hàm này cùng với bất kì giao diện dữ liệu như thế nào, với chỉ ra xúc tích chọn lọc trên thời điểm Gọi hàm. Trên thực tiễn, đoạn code này về cơ bạn dạng là giống cùng với hàm Where thực thụ vào Linq(bên cạnh một vài ba xúc tích và ngắn gọn bình chọn điều kiện). Tuyệt!

Nếu tinc ý thì các bạn cũng sẽ nhận thấy rằng hàm Where của bọn họ là 1 hàm “thuần” (pure function), tức là nó không làm cho thay đổi dữ liệu. Vấn đề này chuẩn cho tất cả những hàm vào Linq (tất yếu, nhằm nó đích thực “thuần”, thì phiên bản thân logic vào hàm “predicate” cũng không được thiết kế biến hóa gì về dữ liệu). Một điểm thú vui nữa của hàm Where là nó là một trong những hàm “lười” (lazy function), tức là trên thời khắc chúng ta Hotline Where(), không có bất cứ xúc tích chọn lọc như thế nào được thực hiện. Chỉ khi chúng ta tìm bí quyết gọi thành phần của chuỗi IEnumerable nhưng mà Where() trả về, cơ hội đó logic “predicate” của chúng ta bắt đầu ban đầu hoạt động.