2012-03-08 66 views
14

Tôi đang quá tải toán tử lessthan trong C# và tôi tự hỏi liệu điều này có cần kiểm tra null hay không. Dưới đây bạn có thể tìm thấy một ví dụ:cần quá tải toán tử <và null kiểm tra

public static bool operator <(MyClass x, MyClass y) 
{ 
    if (x == null && y == null) 
    { 
    return false; 
    } 
    if (x == null) 
    { 
    return true; //false? 
    } 
    if (y == null) 
    { 
    return false; //true? 
    } 
    return x.Value < y.Value; 
} 

Hoặc là điều này đúng:

public static bool operator <(MyClass x, MyClass y) 
{ 
    return x.Value < y.Value; 
} 

Tôi đã không hề tìm thấy bất kỳ hướng dẫn về vấn đề này. Nhưng có lẽ tôi đã bỏ lỡ điều gì đó.

Trả lời

12

Câu trả lời tùy thuộc vào mẫu sử dụng dự định của bạn. Nếu bạn dự định có null trong danh sách kết hợp và bạn muốn xem xét các giá trị null nhỏ hơn giá trị không null, thì việc triển khai của bạn là chính xác; nếu bạn muốn xem xét các giá trị null lớn hơn các đối tượng không rỗng, thì thay vào đó, giá trị trả về đã nhận xét (falsetrue) sẽ được sử dụng. Nếu bạn không có kế hoạch cho phép null trong hỗn hợp, hãy ném một số ArgumentNullException hoặc cho phép NullReferenceException sẽ là lựa chọn đúng đắn.

+1

Ném trẻ em "ArgumentNullException', không bao giờ ném một' NullReferenceException' có chủ định. – Dagrooms

+0

Đó là sự khác biệt giữa "Tôi muốn làm điều này" và "oops." – Dagrooms

1

Toán tử tùy chỉnh nhỏ hơn một phương pháp tĩnh. Hơn nữa, các nhà khai thác trong các tướng thường không nên ném ngoại lệ. Điều này có nghĩa là bạn cần những kiểm tra rỗng đó nếu MyClass là kiểu tham chiếu.

Nhân tiện, thông thường đối với nulls phải nhỏ hơn không nulls, điều này làm cho thành ngữ thực hiện được đề xuất của bạn.

+0

tham số đầu tiên có thể là rỗng như thế nào? – vulkanino

+0

Hoặc bạn chỉ để cho hệ thống ném, không gây hại trong đó (ngoại trừ trường hợp ngoại lệ là hơi ít thích hợp). –

+0

@vulkanino: Tham số đầu tiên có thể là null vì toán tử được thực hiện như một phương thức tĩnh. – Ani

2

Cá nhân tôi sẽ ném một số ArgumentNullException nếu x hoặc ynull, đây phải là một trường hợp ngoại lệ.

+5

'NullReferenceException' không được ném từ mã người dùng, điều đó có nghĩa là có lỗi lập trình. Sử dụng 'ArgumentNullException' để thay thế. – asawyer

+0

@asawyer Chỉ cần chỉnh sửa;) – mdm

+0

@asawyer 'ArgumentNullException' cũng chỉ ra lỗi lập trình. Tôi không chắc là cả hai đều là một quyết định thông minh của khung công tác. –

4

Cả hai cách tiếp cận đều đúng (đối với các giá trị khác nhau của chính xác).

Nếu x hoặc y có thể không có giá trị và có ý nghĩa hợp lệ trong trường hợp của bạn, hãy đi theo phương pháp đầu tiên.

Nếu xy có nhiều khả năng không có giá trị, hãy đi theo thứ hai và để bất kỳ ngoại lệ nào lan truyền tới mã gọi để xử lý.

-1
  1. Đó là một ý tưởng tồi đối với các nhà khai thác quá tải trên lớp học. Đó là ok cho structs mặc dù.

  2. Nếu bạn quyết định quá tải nhà điều hành trên một lớp học, bạn sẽ phải:
    a. Bao gồm kiểm tra null vào logic của bạn
    b. Ném ngoại lệ khi null được chuyển vào
    c. Thực hiện kiểm tra không phải là null và cho phép NullReferenceExceptions (xấu)

Về cơ bản, đó là một ý tưởng tồi để quá tải một nhà điều hành trên một lớp. Tôi muốn biến lớp học của bạn thành một cấu trúc, hoặc chỉ thực hiện một giao diện như IComparable<T>/IEquatable<T> có các hướng dẫn khi sử dụng các giá trị null để so sánh.

+0

Tôi không đồng ý với điều đó - nó thường có ý nghĩa để có các lớp giống như giá trị, đặc biệt kể từ khi hướng dẫn có liên quan (hữu ích) trong .NET nói" nếu nghi ngờ, hãy viết một lớp " –

+0

Ý tưởng tồi tệ hơn là Một toán tử là một giá trị, có thể được so sánh với các giá trị khác.Một lớp là một tham chiếu và không nên được xử lý như một cấu trúc.Tôi chưa thấy bất kỳ cần phải quá tải một toán tử cho một lớp (như –

+1

ví dụ tiêu chuẩn: Lớp phức tạp. Bạn sẽ không quá tải các toán tử? – vulkanino

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