2010-03-23 31 views
17

Nếu tôi bước qua đoạn mã sau, lệnh gọi hàm ReturnOne() bị bỏ qua.Năng suất C# trong phương pháp lồng nhau

static IEnumerable<int> OneThroughFive() 
{ 
    ReturnOne(); 
    yield return 2; 
    yield return 3; 
    yield return 4; 
    yield return 5; 
} 

static IEnumerator<int> ReturnOne() 
{ 
    yield return 1; 
} 

Tôi chỉ có thể giả định trình biên dịch xóa nó ra vì những gì tôi đang làm không hợp lệ. Tôi muốn khả năng cô lập điều tra của tôi thành nhiều phương pháp khác nhau. Điều này có thể không?

Trả lời

30

Bạn không thực sự đang sử dụng kết quả của ReturnOne. Bạn đang gọi phương thức và bỏ qua giá trị trả lại ... có nghĩa là bạn sẽ không bao giờ thực sự thấy bất kỳ mã nào của bạn đang chạy. Bạn có thể làm điều đó như thế này:

static IEnumerable<int> OneThroughFive() 
{ 
    foreach (int x in ReturnOne()) 
    { 
     yield x; 
    } 
    yield return 2; 
    yield return 3; 
    yield return 4; 
    yield return 5; 
} 

C# không (hiện tại ít nhất :) có một loại "năng suất tất cả" xây dựng.

Thực tế là bạn không nhận được bước vào nó không có gì để làm với thực tế rằng bạn đã có một cuộc gọi trong một khối lặp - nó chỉ là cho đến khi bạn bắt đầu sử dụng kết quả của một khối lặp , không có mã nào chạy. Đó là lý do tại sao bạn cần tách biệt tính hợp lệ của đối số khỏi sinh lợi. Ví dụ, hãy xem xét mã này:

public IEnumerator<string> ReturnSubstrings(string x) 
{ 
    if (x == null) 
    { 
     throw ArgumentNullException(); 
    } 
    for (int i = 0; i < x.Length; i++) 
    { 
     yield return x.Substring(i); 
    } 
} 
... 
ReturnSubstring(null); // No exception thrown 

Bạn cần phải viết nó như thế này:

public IEnumerator<string> ReturnSubstrings(string x) 
{ 
    if (x == null) 
    { 
     throw ArgumentNullException(); 
    } 
    return ReturnSubstringsImpl(x); 
} 

private IEnumerator<string> ReturnSubstringsImpl(string x) 
{ 
    for (int i = 0; i < x.Length; i++) 
    { 
     yield return x.Substring(i); 
    } 
} 

Để biết thêm chi tiết, đọc chương 6 của C# in x - mà sẽ xảy ra là một chương miễn phí trong ấn bản đầu tiên :) Grab it here.

+0

có thể bằng cách nào đó tiện dụng ... – Luiscencio

+0

@Jon: Điều gì sẽ xảy ra nếu bạn cố gắng thực sự sử dụng kết quả của 'ReturnSubstrings' đầu tiên? Bạn sẽ nhận được 'NullPointerException' hoặc' ArgumentNullException'? –

+0

Tôi yêu như thế nào, khi đọc chủ đề này, tôi biết rằng jon skeet đã viết câu trả lời này trước khi tôi muốn cuộn xuống phía dưới và nhìn thấy tác giả. @jon, bạn thực sự nên nhận ra nhiều hơn nữa. nhưng bây giờ, cảm ơn một lần nữa vì đã dạy tôi một điều mới mẻ. – fearofawhackplanet

Các vấn đề liên quan