2008-08-19 43 views
12

Tôi biết những gì yield làm, và tôi đã nhìn thấy một vài ví dụ, nhưng tôi không thể nghĩ về các ứng dụng thực tế đời sống, bạn đã sử dụng nó để giải quyết một số vấn đề cụ thể?Ứng dụng thực tế trong cuộc sống là gì?

(Lý tưởng nhất là một số vấn đề mà không thể được giải quyết một số cách khác)

Trả lời

8

Tôi nhận ra đây là một câu hỏi cũ (trước Jon Skeet?) Nhưng tôi đã tự xem xét câu hỏi này gần đây. Thật không may các câu trả lời hiện tại ở đây (theo ý kiến ​​của tôi) không đề cập đến lợi thế rõ ràng nhất của tuyên bố lợi nhuận.

Lợi ích lớn nhất của tuyên bố lợi nhuận là nó cho phép bạn lặp qua các danh sách rất lớn với việc sử dụng bộ nhớ hiệu quả hơn nhiều khi sử dụng danh sách tiêu chuẩn.

Ví dụ: giả sử bạn có truy vấn cơ sở dữ liệu trả về 1 triệu hàng. Bạn có thể lấy tất cả các hàng bằng cách sử dụng một DataReader và lưu trữ chúng trong một List, do đó yêu cầu list_size * row_size byte của bộ nhớ.

Hoặc bạn có thể sử dụng báo cáo lợi nhuận để tạo Iterator và chỉ lưu trữ một hàng trong bộ nhớ tại một thời điểm. Thực tế điều này mang lại cho bạn khả năng cung cấp khả năng "truyền trực tuyến" trên nhiều tập dữ liệu.

Hơn nữa, trong mã sử dụng Iterator, bạn sử dụng vòng lặp foreach đơn giản và có thể quyết định tách ra khỏi vòng lặp theo yêu cầu.Nếu bạn phá vỡ sớm, bạn không buộc phải truy xuất toàn bộ tập dữ liệu khi bạn chỉ cần 5 hàng đầu tiên (ví dụ).

Về:

Ideally some problem that cannot be solved some other way 

tuyên bố Lợi tức không cung cấp cho bạn bất cứ điều gì bạn không thể làm được sử dụng riêng thực hiện tùy chỉnh iterator của bạn, nhưng nó giúp bạn tiết kiệm cần phải viết mã thường phức tạp cần thiết. Có rất ít vấn đề (nếu có) không thể giải quyết nhiều hơn một cách.

Dưới đây là một vài câu hỏi nhiều hơn gần đây và câu trả lời mà cung cấp chi tiết hơn:

Yield keyword value added?

Is yield useful outside of LINQ?

5

thực sự tôi sử dụng nó trong một cách phi truyền thống trên trang web của tôi IdeaPipe

public override IEnumerator<T> GetEnumerator() 
{ 
    // goes through the collection and only returns the ones that are visible for the current user 
    // this is done at this level instead of the display level so that ideas do not bleed through 
    // on services 
    foreach (T idea in InternalCollection) 
     if (idea.IsViewingAuthorized) 
      yield return idea; 
} 

nên về cơ bản nó sẽ kiểm tra nếu xem ý tưởng hiện đang được ủy quyền và nếu nó là nó trả về ý tưởng. Nếu không, nó chỉ bị bỏ qua. Điều này cho phép tôi lưu trữ các ý tưởng nhưng vẫn hiển thị ý tưởng cho người dùng được ủy quyền. Khác tôi sẽ phải kéo chúng mỗi lần dựa trên các điều khoản, khi chúng chỉ được xếp hạng lại sau mỗi 1 giờ.

1

Các toán tử của LINQ trên lớp Enumerable được triển khai dưới dạng trình lặp được tạo bằng câu lệnh yield. Nó cho phép bạn thao tác chuỗi như Select() và Where() mà không liệt kê bất cứ điều gì cho đến khi bạn thực sự sử dụng điều tra trong một vòng lặp, thường bằng cách sử dụng câu lệnh foreach. Ngoài ra, vì chỉ có một giá trị được tính khi bạn gọi IEnumerator.MoveNext() nếu bạn quyết định dừng giữa bộ sưu tập, bạn sẽ lưu hiệu suất truy cập để tính toán tất cả các kết quả.

Bộ lặp cũng có thể được sử dụng để thực hiện các loại đánh giá lười biếng khác khi biểu thức chỉ được đánh giá khi bạn cần. Bạn cũng có thể sử dụng sản lượng để có thêm những thứ ưa thích như coroutines.

1

Một sử dụng tốt cho năng suất là để thực hiện một chức năng trên các yếu tố của một IEnumerable và trả lại kết quả của một loại khác nhau, ví dụ:

public delegate T SomeDelegate(K obj); 

public IEnumerable<T> DoActionOnList(IEnumerable<K> list, SomeDelegate action) 
{ 
    foreach (var i in list) 
     yield return action(i); 
} 
2

Một cách dùng thú là như một cơ chế để lập trình không đồng bộ đặc biệt cho các tác vụ thực hiện nhiều bước và yêu cầu cùng một tập hợp dữ liệu trong mỗi bước. Hai ví dụ về điều này sẽ là Jeffery Richters AysncEnumerator Part 1Part 2. Thời gian chạy đồng thời và phối hợp (CCR) cũng sử dụng kỹ thuật này CCR Iterators.

1

Sử dụng lợi nhuận có thể ngăn chặn việc truyền xuống dưới dạng bê tông. Điều này rất tiện lợi để đảm bảo rằng người tiêu dùng của bộ sưu tập không thao túng nó.

0

Bạn cũng có thể sử dụng yield return để điều trị một loạt các kết quả chức năng như một danh sách. Ví dụ, hãy xem xét một công ty trả tiền cho nhân viên của mình sau mỗi hai tuần. Người ta có thể truy xuất một tập hợp con ngày lập bảng lương dưới dạng danh sách sử dụng mã này:

void Main() 
{ 
    var StartDate = DateTime.Parse("01/01/2013"); 
    var EndDate = DateTime.Parse("06/30/2013"); 
    foreach (var d in GetPayrollDates(StartDate, EndDate)) { 
     Console.WriteLine(d); 
    } 
} 

// Calculate payroll dates in the given range. 
// Assumes the first date given is a payroll date. 
IEnumerable<DateTime> GetPayrollDates(DateTime startDate, DateTime endDate, int  daysInPeriod = 14) { 
    var thisDate = startDate; 
    while (thisDate < endDate) { 
     yield return thisDate; 
     thisDate = thisDate.AddDays(daysInPeriod); 
    } 
} 
Các vấn đề liên quan