2011-06-20 48 views
9

Tôi đã cố gắng sử dụng Enumerable.SequenceEqual(x,y) như tôi mong đợi nó hoạt động dựa trên phương thức Object.Equals(x,y), trả về false nếu x hoặc y là null và true nếu cả hai đều là rỗng (đối với trường hợp null).Tại sao Enumerable.SequenceEqual ném ngoại lệ nếu tham số bất kỳ là null?

Tuy nhiên Enumerable.SequenceEqual(x,y) ném ngoại lệ nếu tham số bất kỳ là tham chiếu null và sẽ không trả về true nếu được cung cấp hai giá trị rỗng. Trong mã của tôi, tôi kiểm tra tính bình đẳng của bộ sưu tập khá thường xuyên vì vậy tôi đã tạo ra một phương thức bắt chước hành vi Object.Equals cho chuỗi nhưng tôi tự hỏi logic đằng sau hành vi mặc định như thế nào và có thể có phương pháp hiện tại không có ngoại lệ về null không? Không.

+1

Vâng, thực tế là tham số đầu tiên là 'null' ném một ngoại lệ, có ý nghĩa, vì nó là một phương pháp mở rộng. Nó thường được gọi là 'x.SequenceEqual (y)' và do đó bắt chước 'x.Equals (y)', nó cũng sẽ ném nếu 'x' trong đó' null'. –

Trả lời

4

Vâng, MSDN documentation tuyên bố rõ ràng rằng nó ném một số ArgumentNullException trong trường hợp bất kỳ một trong số nào được truyền trong dãy là null. Tôi cho rằng đó là để duy trì sự nhất quán với "hành vi tiêu chuẩn", nơi một đối tượng ném một số NullReferenceException khi bạn cố gắng dereference nó. Hãy xem xét điều này:

List<int> foo = null; 
foo.SequenceEqual(new List<int>()); 

Điều này sẽ là ok vì SequenceEqual là phương pháp tiện ích và do đó có thể xử lý đối tượng rỗng nhưng cũng sẽ gây nhầm lẫn. Mọi phương thức mở rộng do Linq cung cấp đều tuân theo hành vi này theo như tôi biết. Ngoài ra, bạn không cần phải xử lý các trường hợp null đặc biệt cho mọi phương thức mở rộng (bạn sẽ cần phải đồng ý về hành vi hợp lý và thêm logic bổ sung và duy trì và kiểm tra nó). Nói rằng nó là bất hợp pháp làm cho nó mạnh mẽ hơn (chống lại lỗi logic) và nhất quán từ một quan điểm khung. Tôi sử dụng LINQ rất nhiều và không bao giờ gặp phải vấn đề đó - tôi chỉ đảm bảo rằng tất cả các chuỗi của tôi không phải là rỗng. Giảm rất nhiều mã lộn xộn (loại bỏ rất nhiều kiểm tra null từ mã).

2

Điểm mà tại đó nó đang kiểm tra sự bình đẳng chuỗi không phải là khi ngoại lệ đó được ném ra. Nó đang được ném trước đó như một trình xác nhận đối số. Hãy xem xét phương pháp:

public static bool SequenceEquals<T>(this IEnumerable<T> source, IEnumerable<T> target) 
{ 
    // Stuff 
} 

Chúng tôi rõ ràng cần phải kiểm tra xem sourcetarget không null, bởi vì nếu bất kỳ trong số đó là, sau đó chúng tôi không thể kiểm tra cho sự bình đẳng tự. Đây là trạng thái không thể thực hiện được và kết quả của SequenceEquals phải được điều chỉnh bởi nội dung của các số đếm, chứ không phải trạng thái của số đếm. Nếu nó bao gồm sau này, khi trả lại false, người gọi sẽ biết liệu nó có thực sự không thành công do các chuỗi không bằng nhau hoặc liệu một hoặc cả hai số đếm là null?

Nếu chúng tôi không ném một số ArgumentNullException vào đây, CLR sẽ ném một số NullReferenceException khi bạn thử và truy cập một trong các số null. Đơn giản chỉ cần nói Object reference not set to an instance of an object là ít hơn rất nhiều hữu ích sau đó The argument <something> cannot be null.

Hãy nhớ rằng loại ngoại lệ được ném thường là một trong những chỉ báo hữu ích nhất về số lý do tại sao một ngoại lệ được ném.

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