2012-12-18 26 views
12

Tôi tò mò nếu có ai có bất kỳ quy tắc hay thực hành tốt nhất nào khi trả lại số hoãn IEnumerable<T> hoặc gọi ToArray() trên đó trước khi trả lại một hàm. Ví dụ, như người tiêu dùng của một API, tôi nghĩ rằng tôi muốn cho một phương pháp như IEnumerable<Widget> GetWidgets() để ném một HttpException khi tôi gọi nó và không có nó ném khi tôi liệt kê các kết quả.Khi nào biểu mẫu không hợp lệ trả lại số bị hoãn lại là số

public IEnumerable<Widget> GetWidgets(IEnumarable<int> widgetIds) { 
    return widgetIds.Select(id => GetWidgetFromWidgetWebService(id)); 
} 
+0

Tôi không thể nghĩ ra một lần duy nhất tôi từng muốn trả lại IEnumerable bị trì hoãn và rất nhiều khi tôi đã vô tình thực hiện nó và phá vỡ tất cả các loại mã. – BenCr

+0

Nhưng, không phải ngoại lệ bằng cách ném một trong hai cách? Ít nhất trong trường hợp đó họ sẽ làm việc theo cùng một cách. – rae1

+1

@ rae1n Có, ngoại lệ sẽ được ném theo một trong hai cách, nhưng hãy tưởng tượng một 'IEnumerable 'bị chuyển qua một hoặc hai lớp chỉ để có ngoại lệ được ném vào một trang gọi cách xa nơi bộ sưu tập gốc được trả về. – joshperry

Trả lời

6

Tôi luôn muốn trả lại số hoãn lại IEnumerable<T> khi không có tác dụng phụ đáng kể nào bị trì hoãn. Nếu đếm được dựa trên một bộ sưu tập nội bộ có thể thay đổi, ví dụ, tôi muốn đánh giá nó trước.

Tuy nhiên, nếu đếm được tính, v.v, thì tôi thường hoãn nó.

+0

Người gọi có thể luôn gọi 'ToList() 'và bắt buộc đánh giá ngay lập tức nếu muốn. Tôi nghĩ tốt nhất là để người gọi thực hiện lựa chọn này, trừ khi, như bạn đã nói, có lý do chính đáng là không. –

+0

@ JonB Đó là suy nghĩ của tôi - Tôi thích cho phép tối ưu hóa khi có thể. –

+2

Một ngoại lệ sẽ là khi bạn chuyển 'IEnumerable' vào một ngữ cảnh mà nó sẽ không được _possible_ để liệt kê nó. Ví dụ, khi 'IEnumerable ' được tạo ra bằng cách sử dụng ngữ cảnh EF sẽ được xử lý theo thời gian liệt kê. Khác hơn thế, tôi đồng ý rằng để lại nó trì hoãn là tốt hơn cho thành phần. –

1

Trong trường hợp bạn đếm được có thể được thực tế dự kiến ​​sẽ ném, háo hức đánh giá nó (nếu có thể). Bạn không muốn lỗi xảy ra ở một nơi xa xôi không liên quan đến nguyên nhân của lỗi. Bạn muốn lỗi đúng nơi nó được gây ra.

Sau khi tất cả, phương pháp đã không hoàn thành tên của nó quảng cáo, vì vậy nó nên ném.

Tôi thường thay đổi kiểu trả về thành IList<T> trong những trường hợp như vậy để ghi lại rằng nó thực hiện háo hức.

+0

Tôi thực sự thích cố gắng thể hiện bằng mã của tôi, ngụ ý ý định nếu bạn muốn. Vấn đề duy nhất tôi có với việc trả về 'IList ' trong những trường hợp đó là nó nói "Này, đây là một bộ sưu tập có thể thay đổi". Tôi không chắc chắn một lựa chọn tốt hơn là gì; có lẽ 'T []', có lẽ 'IReadOnlyList '? – joshperry

+0

@ joshperry Tôi rất có xu hướng không sửa đổi bộ sưu tập vì vậy tôi không có vấn đề đó. Tôi thường tạo ra một cái mới dễ chết vì C# 3.0. – usr

+0

Không có gì để nói rằng một 'IList 'được thực hiện háo hức. Có thể, và thường mong muốn, có một 'IList ' chỉ thực hiện những gì cần thiết vì nó là cần thiết. –

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