Hành vi dự kiến ​​khi một yêu cầu cho bộ sưu tập sẽ không có mục nào


13

Giả sử bạn được cung cấp ...

List<Thing> theThings = fubar.Things.All();

Nếu không có gì để trở lại, bạn sẽ mong chờ điều gì ở fubar.Things.All () sẽ trở lại?

Chỉnh sửa: Cảm ơn các ý kiến. Tôi sẽ đợi một chút và chấp nhận mục có nhiều nhất.

Tôi đồng ý với các câu trả lời cho đến nay, đặc biệt là những người đề xuất một bộ sưu tập trống. Một nhà cung cấp đã cung cấp một API với một số cuộc gọi tương tự như ví dụ trên. Một nhà cung cấp đã kiếm được 4,6 triệu đô la doanh thu thông qua (các) API của họ vào năm ngoái, BTW. Họ làm điều gì đó về cơ bản tôi không đồng ý - họ ném một ngoại lệ.


Có vẻ là một sự đồng thuận khá vững chắc [ở đây] [1]: Bộ sưu tập trống. Luôn luôn. [1]: stackoverflow.com/questions/1969993/ Kẻ
Jesse C. Choper

Kiểu dữ liệu để làm Thingsgì? Nếu nó có ý nghĩa để Thingstrường trả về null, thì có nghĩa là bạn sẽ nhận được một ngoại lệ vì bạn đã không kiểm tra null trước khi bạn gọi đến All(). Tuy nhiên, tôi đồng ý với những người nghĩ fubar.Thingsnên trả lại một bộ sưu tập trống thay vì null.
Colin D

Tôi thấy những gì bạn đang nhận được, Colin. Trong trường hợp này, bạn có thể giả sử Mọi thứ tồn tại và All () là tĩnh. Ngoại lệ là cụ thể cho bộ sưu tập trống, không phải là một số lý do khác.
abscode

OMG họ ném một ngoại lệ ...! o_O
Stuart Marks

Bây giờ, câu hỏi thú vị hơn sẽ là lý do gì trên trái đất mà bất kỳ ai cũng có thể phải ném trong một trường hợp chung như vậy, hoặc điều gì làm cho vụ án trở nên đặc biệt để đảm bảo Ném?
Martin Ba

Câu trả lời:


29

Trong hai khả năng (nghĩa là trả lại một nullhoặc trả lại một bộ sưu tập trống) tôi sẽ chọn trả về một bộ sưu tập trống, bởi vì nó cho phép người gọi bỏ qua kiểm tra giá trị được trả về. Thay vì viết cái này

List<Thing> theThings = fubar.Things.All();
if (theThings != null) {
    for (Thing t : theThings) {
        t.doSomething();
    }
}

họ sẽ có thể viết điều này:

List<Thing> theThings = fubar.Things.All();
for (Thing t : theThings) {
    t.doSomething();
}

Đoạn mã thứ hai này ngắn hơn và dễ đọc hơn, bởi vì mức lồng nhau thấp hơn một.


2
Tôi nghĩ rằng tôi cũng sẽ dễ hiểu hơn về mặt khái niệm vì 'bộ trống rỗng' (không có mục nào). Null là "không có tập hợp", điều này khá khác biệt. (Điều này cũng sẽ bao gồm những thứ không hợp lý logic - tập hợp tất cả các mục kỳ lạ thậm chí nên trống, không rỗng). Tôi thực sự không chắc chắn những gì (về mặt logic) sẽ tạo thành một bộ null ... (ngay cả khi bạn đang khỏa thân trên một hòn đảo, tài sản của bạn là một bộ trống rỗng, không phải là một bộ null)
Clockwork-Muse

@ X-Zero Nhưng nếu bạn cởi trần, "tài sản trong ba lô" có thể trả lại một bộ null, vì bạn thậm chí không có ba lô trên người. Nó có thể là một BackpackNotFoundException, nhưng chỉ khi nó thực sự bất ngờ. Nó nên là một trạng thái bình thường trong một trò chơi sinh tồn trên đảo.
Izkata

Kiểm tra null thêm là những gì giúp tôi ngủ vào ban đêm.
Joel B

6

Tôi sẽ mong đợi một danh sách trống. theThingsvẫn sẽ là một đối tượng, nhưng theThings.Counthoặc theThings.size()sẽ trở lại 0.


5

Các vấn đề thiết kế như thế được giải quyết bằng mẫu Null Object

... Thay vì sử dụng tham chiếu null để truyền đạt sự vắng mặt của một đối tượng (ví dụ: khách hàng không tồn tại), người ta sử dụng một đối tượng thực hiện giao diện dự kiến, nhưng phần thân phương thức trống. Ưu điểm của phương pháp này so với triển khai mặc định đang hoạt động là đối tượng Null rất dễ đoán và không có tác dụng phụ: nó không làm gì cả.

Ví dụ, một hàm có thể truy xuất danh sách các tệp trong một thư mục và thực hiện một số hành động trên mỗi tệp. Trong trường hợp thư mục trống, một phản hồi có thể là ném ngoại lệ hoặc trả về tham chiếu null thay vì danh sách. Do đó, mã mong đợi một danh sách phải xác minh rằng trên thực tế nó có một mã trước khi tiếp tục, điều này có thể làm phức tạp thiết kế ...

Đề xuất đặc biệt áp dụng trong trường hợp của bạn (trở lại Listkhi không có Things) là:

... Thay vào đó, bằng cách trả về một đối tượng null (tức là một danh sách trống ), không cần phải xác minh rằng giá trị trả về thực tế là một danh sách. Hàm gọi có thể đơn giản lặp lại danh sách như bình thường, không có hiệu quả. Tuy nhiên, vẫn có thể kiểm tra xem giá trị trả về có phải là đối tượng null hay không (ví dụ: danh sách trống) và phản ứng khác nhau nếu muốn.


3

Bạn nên, IMHO, trả về giá trị EMPTY. Tôi không biết về C #, nhưng trong Java chúng ta có điều này:

  List list = Collections.EMPTY_LIST;
  Set set = Collections.EMPTY_SET;
  Map map = Collections.EMPTY_MAP;

  // For the type-safe 
  List<String> s = Collections.emptyList();
  Set<Long> l = Collections.emptySet();
  Map<Date> d = Collections.emptyMap();

http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html


1
Tương đương C # là Enumerable.Empty<T>(), trả về một khoảng trống IEnumerable<T>(xem msdn.microsoft.com/en-us/l Library / bb341042.aspx )
Avner Shahar-Kashtan

1
Các tài liệu hiện tại đang ở đây: docs.oracle.com/javase/7/docs/api/java/util/Collections.html - các tài liệu 1.4.2 hiện đã được khoảng mười năm.
Stuart Marks

2

Tôi sẽ trả về một bộ sưu tập trống thay vì trả về giá trị null vì theo cách đó bạn có thể tránh việc viết xác minh null trong mã gọi.


2

Hai giải pháp họ có nghĩa là những thứ khác nhau.

Nếu không có thứ gì bạn trả lại, bạn LUÔN trả lại một bộ sưu tập trống! Lấy trường hợp của một danh sách thư mục. Nếu không có tệp nào trong thư mục, bạn trả về một tập hợp các tệp trống.

Mặt khác, nếu thư mục không tồn tại, điều đó không thực sự phù hợp. "Tôi không thể trả lại bất cứ điều gì" có nghĩa là một cái gì đó hoàn toàn khác. Trong trường hợp đó, bạn nên trả về null hoặc ném ngoại lệ tùy theo tình huống, đừng trả lại một bộ sưu tập trống như không có gì sai.


Giải thích rất hợp lý. Kết quả trả về không nên bao gồm trạng thái không hợp lệ, chúng tôi có ngoại lệ cho việc này.
Ivaylo Slavov
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.