2011-04-27 40 views
11

tôi nghĩ phương pháp này là hợp lệ nhưng tôi đã sai:Toán tử '==' cho loại T?

static void Equals<T>(T x, T y) 
{ 
    return x == y; //operator == can't be applied to type T 
} 

Sau khi đọc specifiation (§7.2.4 trong v3.0 và §7.3.4 trong v4.0):

7.2.4 hành binary độ phân giải quá tải

một hoạt động của y hình thức x op, nơi op là một overloadable điều hành nhị phân, x là một biểu hiện của loại x, và y là một biểu hiện của loại Y, được xử lý như sau:

  • Tập hợp các ứng cử viên vận hành do người dùng định nghĩa cung cấp bởi X và Y đối với các nhà điều hành hoạt động op (x, y) được xác định. Bộ bao gồm sự kết hợp của các toán tử ứng viên được cung cấp bởi X và toán tử ứng cử viên do Y, xác định sử dụng các quy tắc §7.2.5. Nếu X và Y cùng loại, hoặc nếu X và Y bắt nguồn từ một loại cơ sở chung , thì chia sẻ toán tử ứng cử viên chỉ xuất hiện trong tập hợp kết hợp một lần.

  • Nếu bộ ứng cử viên khai thác người dùng định nghĩa là không trống rỗng, sau đó điều này trở thành tập các nhà khai thác ứng cử viên cho các hoạt động . Nếu không, các triển khai op nhị phân được xác định trước nhị phân, bao gồm các biểu mẫu đã được dỡ bỏ của chúng, trở thành tập hợp các toán tử ứng cử viên cho hoạt động . Việc triển khai được xác định trước của nhà điều hành đã cho được chỉ định trong mô tả của toán tử (từ 7,7 đến §7,11).

  • Quy tắc giải quyết quá tải của §7.4.3 được áp dụng cho bộ toán tử ứng cử viên để chọn toán tử tốt nhất đối với danh sách đối số (x, y) và toán tử này trở thành kết quả của quá trình giải quyết quá tải . Nếu độ phân giải quá tải không chọn được một toán tử tốt nhất, một lỗi biên dịch sẽ xảy ra.

Trong bước 2 Tôi nghĩ rằng thực hiện được xác định trước điều này nên được áp dụng:

bool operator ==(object x, object y); 
bool operator !=(object x, object y); 

kể từ khi tất cả mọi thứ trong C# bắt nguồn từ Object. Làm thế nào một lỗi biên dịch có thể xảy ra ở bước 3? Tôi không nghĩ rằng có thể "độ phân giải quá tải không thể chọn" trong trường hợp này.

EDIT Câu hỏi đặt ra hiện lên trong đầu tôi khi tôi đã thực hiện một cái gì đó như thế này:

class EnumComparer<TEnum> : IEqualityComparer<TEnum> 
{ 
    public bool Equals(TEnum x, TEnum y) 
    { 
     return x == y; 
    } 
    public int GetHashCode(TEnum obj) 
    { 
     return (int)obj; 
    } 
} 

Tôi sợ rằng tôi cần phải xây dựng một biểu hiện và gọi nó dynamicly trong Equals phương pháp.

+0

thể trùng lặp của [C# so sánh hai giá trị chung] (http://stackoverflow.com/questions/488250/c-compare-two-generic-values) –

+0

FWIW, '(object) x == (đối tượng) y' là hợp lệ - nhưng hãy xem xét '(đối tượng) 1 == (đối tượng) 1' làm lý do không mong muốn điều này. Chỉ cần giúp 'T' cùng với một không chung chung. –

+1

Thảo luận là một chút trừu tượng, nhưng Eric Lippert đã chỉ ra rằng đó là một quan niệm sai lầm chung rằng mọi thứ * xuất phát từ 'Object'. http://blogs.msdn.com/b/ericlippert/archive/2009/08/06/not-everything-derives-from-object.aspx Điểm liên quan mà anh đề cập là các tham số kiểu không lấy được từ bất kỳ thứ gì. –

Trả lời

20

Tốt cho bạn đọc thông số kỹ thuật, nhưng bạn đã dừng đọc quá sớm. Có bạn đọc thêm bạn đã có thể nhận để bit này:


Các loại tài liệu tham khảo các nhà khai thác bình đẳng được xác định trước yêu cầu một trong các cách sau:

  • Cả hai toán hạng là một giá trị của một loại biết đến là một kiểu tham chiếu hoặc null dạng chữ. Hơn nữa, một chuyển đổi tham chiếu rõ ràng tồn tại từ kiểu toán hạng sang kiểu toán hạng khác.

  • Một toán hạng là giá trị kiểu T trong đó T là tham số kiểu và toán hạng khác là giá trị rỗng. Hơn nữa T không có ràng buộc kiểu giá trị.

Trừ khi một trong những điều kiện này là đúng, xảy ra lỗi liên kết. (*)


Các lỗi không phải là từ độ phân giải quá tải; lỗi là độ phân giải quá tải có thể đã chọn toán tử bình đẳng kiểu tham chiếu được xác định trước và bạn không có kiểu tham chiếu.

Hãy xem xét mã của bạn. Điều gì ngăn T từ một loại giá trị không có toán tử bình đẳng được xác định trên nó? Không có gì. Giả sử chúng ta đã quay trở lại phiên bản đối tượng; cả hai toán hạng sẽ hộp đến các vị trí khác nhau và do đó tham chiếu-bất bình đẳng, ngay cả khi chúng có cùng nội dung. Kể từ đó là chậm, khó hiểu và sai, nó là bất hợp pháp thậm chí cố gắng.

Tại sao bạn đang cố thực hiện việc này ngay từ đầu? Nếu phương pháp của bạn hoạt động, điều này không đúng, thì phương pháp của bạn sẽ là tồi tệ hơn hơn là chỉ sử dụng == ở vị trí đầu tiên. Giá trị bạn định thêm vào thế giới với phương pháp này là gì?


(*) Tôi đã báo cáo lỗi ngữ pháp trong câu này với người bảo trì thông số.

+0

Cảm ơn câu trả lời của bạn. Xem bản chỉnh sửa của tôi để biết câu hỏi này đến với tâm trí của tôi như thế nào. –

+0

Xem câu hỏi liên quan: http://stackoverflow.com/questions/5829441/equalitycomparert-default-isnt-clever-enough –

-1

sử dụng .Equals() phương pháp và chắc chắn rằng các T thực hiện IComparable

+6

'IComparable []' là * đặt hàng *; Bằng (với 'GetHashCose()' và tùy chọn 'IEquatable ') là bình đẳng. –

+1

Typo: GetHashCode –

7

Đó có thể sẽ có tác dụng nếu nó biết rằng where T : class, làm một so sánh tham khảo. Các nhà khai thác thường có rất ít sự hỗ trợ với Generics, nhưng có nhiều cách giải quyết khác nhau. MiscUtil cung cấp indirect support for operators về generics, nếu không EqualityComparer<T>.Default.Equals(x,y) là một lựa chọn tốt.

+0

Cảm ơn! Tôi chỉ muốn thực hiện một so sánh cho enums. Xem chỉnh sửa của tôi. –

+4

@Danny - thử 'EqualityComparer .Default.Equals (x, y)' rồi –

+0

LOL! Tôi đã sai hướng! Cảm ơn rất nhiều vì gợi ý! –

1

Tôi thích sử dụng EqualityComparer<T>.Default cho việc này.

Phương pháp này dựa trên phương pháp Equals bị ghi đè, nhưng sử dụng IEquatable<T> khi khả dụng, tránh đánh boxing trên các loại giá trị triển khai.

EqualityComparer<T>.Default.Equals(x, y) 
Các vấn đề liên quan