2012-11-14 26 views
11

Tôi đang viết một số xét nghiệm đơn vị và sự khẳng định sau thất bại:Tại sao Assert.AreEqual() truyền đến đối tượng trước khi so sánh?

Assert.AreEqual(expected.Episode, actual.Episode); 

Nếu tôi gọi đây là thay vào đó, nó thành công:

Assert.IsTrue(expected.Episode.Equals(actual.Episode)); 

tôi đã giả định rằng Assert.AreEqual() rốt cuộc gọi phương thức Equals() cho nhập nó, trong trường hợp này là Episode.Equals().

Tuy nhiên, dưới tấm chăn trong Microsoft.VisualStudio.TestTools.UnitTesting.Assert tôi thấy đoạn mã sau (dịch ngược bởi ReSharper):

public static void AreEqual<T>(T expected, T actual, string message, params object[] parameters) 
{ 
    if (object.Equals((object)expected, (object)actual)) 
     return; 
    Assert.HandleFail... 
} 

Điều này ngụ ý với tôi rằng phương pháp AreEqual() được đúc cảvà actual đến object để buộc sử dụng phương thức cơ sở Equals() thay vì quá tải tôi đã viết trong lớp Episode. Phương thức cơ sở sẽ chỉ kiểm tra xem các tham chiếu có giống nhau hay không.

Tôi có hai câu hỏi:

  1. là lời giải thích của tôi thực sự chính xác, hoặc tôi đã bị mất cái gì?
  2. Tại sao khung làm việc muốn sử dụng đối tượng.Equals() thay vì quá tải của phương thức đó?

Nếu nó có liên quan, đây là phương pháp của tôi:

public bool Equals(Episode other) 
{ 
    return Number == other.Number && 
      CaseNote.Equals(other.CaseNote) && 
      Patient.Equals(other.Patient); 
} 
+0

Offtopic: phiên bản nào của ReSharper có thể dịch ngược? – sll

+0

Tôi không chắc nó đã ở đó bao lâu nhưng ít nhất là v5 trong kinh nghiệm của tôi ... lần đầu tiên bạn F12 (đi khai báo) trên một đối tượng bên trong nó sẽ hỏi bạn muốn làm gì; một trong các tùy chọn là để dịch ngược. Ngoài ra còn có một trình giải mã độc lập miễn phí từ Jetbrains. –

+1

btw, phương thức được hiển thị là * quá tải *, không phải là 'ghi đè'. –

Trả lời

6

Nó được sử dụng object.Equals(object,object), trong đó giao dịch với những thứ như:

  • là họ tham chiếu giống nhau không?
  • là một trong hai hoặc một tham chiếu null?

sau đó tiếp tục sử dụng x.Equals(y)sau nó đã xử lý những điều đó. Nó phải chuyển chúng đến objectvì đó là những gì object.Equals(object,object) mất. Truyền tới object cũng tránh được một số biến chứng với Nullable<T> (vì một hộp T? hoặc là null hoặc được đóng hộp thường lệ T).

Tuy nhiên, nó có thể cũng đã được triển khai như:

if (EqualityComparer<T>.Default.Equals(expected,actual)) 
    return; 

mà xử lý Nullable<T>, IEquatable<T>, struct vs class, và một vài tình huống khác mà không có bất kỳ boxing.

Nhưng: việc triển khai hiện tại thực hiện công việc và hộp không thường xuyên không phải là kết thúc của thế giới (và: boxing không phải là vấn đề nếu loại của bạn là class).

+0

Lưu ý rằng [kiểm tra null bằng cách truyền tới đối tượng trên 'Nullable ' có tác động hiệu suất có thể tránh được] (http://stackoverflow.com/q/12396457/50776) (không phải lỗi của bạn, hãy nhớ bạn). – casperOne

+0

@casperOne thực sự, đó là lý do tại sao * nếu tôi đã viết nó * Tôi đã sử dụng 'EqualityComparer ', mà ** không ** chịu đựng điều này. –

+0

Trong khi câu trả lời này là chính xác, nó không giải thích được tại sao OP lại thấy sai khi anh ta trông đợi sự thật. Vấn đề chính ở đây là anh ta chỉ thực hiện 'Equals (Episode other)' và không phải 'Equals (object other)' nữa. – Servy

4

Trong mã của bạn, bạn cũng cần ghi đè lên Equals(object other) (và cũng cần ghi đè GetHashCode).

Chỉ cần thêm video này vào mã của bạn

public bool Equals(Episode other) 
{ 
    return Number == other.Number && 
      CaseNote.Equals(other.CaseNote) && 
      Patient.Equals(other.Patient); 
} 

public override bool Equals(object other) 
{ 
    Episode castOther = other as Episode; 
    if(castOther == null) 
     return false; 
    return this.Equals(castOther); 
} 

public override int GetHashCode() 
{ 
    //TODO: Implement using the members you used in "Equals(Episode other)" 
    throw new NotImplmentedExecption(); 
} 

Nên nhớ cho GetHashCode nếu hai đối tượng đều bình đẳng họ phải cũng trở lại mã băm bình đẳng. Đây là một sơ đồ nhanh để giúp hình dung.

enter image description here

Bạn có thể muốn kiểm tra CaseNotePatient cho các vấn đề tương tự.

+0

Cảm ơn câu trả lời hữu ích của bạn. Tôi nhận ra rằng đây là * thực sự * lý do mã của tôi trả về các kết quả khác nhau cho hai xác nhận. –

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