2010-11-05 20 views
9

Chỉ cần đọc bài viết MSDN về ghi đè các nhà khai thác bình đẳng hereCast cho đối tượng trước khi kiểm tra null trong trọng Equals

Đoạn sau confuses me ...

// If parameter cannot be cast to Point return false. 
TwoDPoint p = obj as TwoDPoint; 
if ((System.Object)p == null) // <-- wtf? 
{ 
    return false; 
} 

Tại sao lại có một dàn diễn viên để Object đây để thực hiện so sánh null?

+1

TwoDPoint là gì? Có thể là một loại giá trị của nó :-D – Grzenio

+0

không. Kiểm tra các liên kết ... – jgauffin

+0

Họ có một hướng dẫn tốt hơn cho Visual Studio 2012. Họ đã không đặt liên kết trong bài viết năm 2005, vì vậy tôi đặt nó ở đây: [Làm thế nào để: Xác định giá trị bình đẳng cho một loại (C# Lập trình Hướng dẫn) ] (http://msdn.microsoft.com/en-us/library/dd183755 (v = vs.110) .aspx). – Brk

Trả lời

9

Toán tử áp dụng thông qua phân tích tĩnh (và quá tải), không phải phương thức ảo (ghi đè). Với dàn diễn viên, nó đang thực hiện kiểm tra bình đẳng tham chiếu. Không có dàn diễn viên, nó có thể chạy toán tử TwoDPoint. Tôi đoán đây là để tránh các vấn đề khi một nhà điều hành được thêm vào.

Cá nhân, tuy nhiên, tôi muốn thực hiện kiểm tra tham chiếu một cách rõ ràng với ReferenceEquals.

+0

+1 ... phong cách này rõ ràng là khủng khiếp khó hiểu (câu hỏi này đã xuất hiện nhiều lần). 'ReferenceEquals' tồn tại, nó nên được sử dụng. –

+0

Bài viết MSDN sau đó tiếp tục giải thích lý do tại sao ReferenceEquals nên được sử dụng :) –

+0

Bạn sẽ nhận được một stackoverflow, như tôi đã làm, khi bạn so sánh đối tượng của bạn để null 'a == null', nó sẽ chạy lại ghi đè của bạn' == ' hoặc '! =' hơn và hơn, cho đến khi nó bị treo. Tuy nhiên, – ppumkin

0

Để bắt buộc sử dụng phương pháp Đối tượng bằng chứ không phải là phiên bản quá tải của riêng ... chỉ là một ...

+0

Có, nhưng * tại sao *? – jgauffin

0

Đây không phải là vô ích. Nếu không có diễn viên đó, toán tử == bị quá tải sẽ được gọi là đệ quy ...

+0

Không. Tôi vừa thử đoạn mã mà không có dàn diễn viên. – jgauffin

+0

@jgauffin: Tôi đã giả định rằng mã đã quá tải toán tử ==, thay vào đó là quá tải Bằng. Trong trường hợp này, tôi không thấy lý do nào để làm điều đó, ngoài việc tránh lỗi nếu toán tử == được giới thiệu sau này như @Marc Gravell gợi ý. –

+0

Điểm của bài viết là bạn không thể ghi đè bằng và quá tải == mà không sử dụng một diễn viên để đối tượng. Nếu bạn làm thế, bạn nhận được một NullReferenceException khi bạn cố gắng làm (myVariable == null). Nhưng tôi đồng ý về việc sử dụng ReferenceEquals. – tandrewnichols

0

dưới đây là dòng mà không được dàn diễn viên

TwoDPoint p = obj as TwoDPoint 

sự khác biệt với các diễn viên "bình thường" là việc sử dụng "As" nó không làm tăng một ngoại lệ nếu đối tượng không phải là "cast". Trong trường hợp này nếu "p" không phải là TwoDPoint Loại sẽ không tăng ngoại lệ (không hợp lệ) nhưng trả lại giá trị rỗng.

if ((System.Object)p == null) // <-- wtf? 
{ 
    return false; 
} 

kiểm tra mã này nếu các diễn viên diễn ra tốt đẹp nếu không p nên được null vì lý do trên

+1

Ông hỏi tại sao diễn viên '(System.Object) 'lại ở đó, không có gì khác. – jgauffin

+0

bạn đúng Tôi chỉ hiểu lầm câu hỏi :-) –

3

Không! nếu bạn không làm điều đó, thời gian chạy sẽ bắt đầu một cuộc gọi đệ quy đến toán tử bình đẳng, bạn chỉ trong đó kết quả trong đệ quy vô hạn và, do đó, một tràn ngăn xếp.

+1

Không. Nó sẽ không. Hãy thử mã .. – jgauffin

+0

Có, mà không có diễn viên nó sẽ recurse cho đến khi 'StackOverflow' – ppumkin

0

Lưu ý rằng đây là tài liệu VS 2005. Tôi đoán những người viết tài liệu cũng có cùng một câu hỏi và không thể đưa ra câu trả lời hay; ví dụ đã được thay đổi cho VS 2008. Dưới đây là current version:

public bool Equals(TwoDPoint p) 
{ 
    // If parameter is null, return false. 
    if (Object.ReferenceEquals(p, null)) 
    { 
     return false; 
    } 

    // Optimization for a common success case. 
    if (Object.ReferenceEquals(this, p)) 
    { 
     return true; 
    } 

    // If run-time types are not exactly the same, return false. 
    if (this.GetType() != p.GetType()) 
     return false; 

    // Return true if the fields match. 
    // Note that the base class is not invoked because it is 
    // System.Object, which defines Equals as reference equality. 
    return (X == p.X) && (Y == p.Y); 
} 
Các vấn đề liên quan