2016-02-03 30 views
5

Performansa duyarlı bir programda, IEquatable<T>.Equals() ve Object.Equals'u (benim durumumdaki kutucuktan kaçınmak için) açıkça aramaya çalışıyorum. En iyi çabalarıma rağmen, derleyici yerine Object.Equals()'u seçiyor. Bir yapmacık örnek sınıfı:Derleyici hatalı bir aşırı yükleme çağrılıyor IEquatable <T> .Equals

class Foo : IEquatable<Foo> 
{ 
    public bool Equals(Foo f) 
    { 
     Console.WriteLine("IEquatable.Equals"); 
     return true; 
    } 

    public override bool Equals(object f) 
    { 
     Console.WriteLine("Object.Equals"); 
     return true; 
    } 
} 

Eşit yapmacık kod sorunu göstermektedir:

// This calls IEquatable<Foo> 
Foo f = new Foo(); 
f.Equals(f); 

// This calls Object.Equals 
IEquatable<Foo> i = new Foo(); 
i.Equals(i); 

bu kodun çıktısını geçerli:

IEquatable.Equals 
Object.Equals 

okudum Jon Skeet en article on overloading ve hala uzakta geldi Buradaki problemi anlama. Bu yüzden sorum şu: Yukarıdaki i değişkeninde IEquatable<Foo>.Equals'u nasıl açıkça arayabilirim?

+6

A 'Foo' ** bir' IEquatable '. Bir 'IEquatable '** **' Foo' DEĞİLDİR. Bu, bunun neden böyle çalıştığını daha açık bir hale getiriyor - spesifik olarak, neden "public bool Equals (Foo f)", "IEquatable " ile aranamaz? –

+0

Eğer 'i' * 'nin bir 'Foo' olduğuna, sonra' i.Equals'a ((Foo) i); Ancak, tabi ki, eğer türünden emin iseniz, bu ne zaman 'ben' türünün beyanı değil mi? –

+1

İlgisiz bir notta, bunun ne kadar harika bir ilk soru olduğunu söyleyebilirim - probleminizin açık bir beyanını, tekrarlanabilir kodu, çıktıyı, beklenen çıktının açık bir ifadesini verdiniz ve son olarak bağımsız araştırmaları gösterdiniz - Bir Harvardınız ve Stack Overflow'a hoş geldiniz :) –

cevap

5

Seçilen ikinci aşırı yükün neden arayan türü ile alakasız olmasının nedeni. Bunun yerine, Equals'a ilettiğiniz argüman türü ile ilgilidir. Yani, f.Equals(i)'u arasanız bile, object.Equals yöntemi seçilecektir. Nedeni basit, derleyici en uygun aşırı yükü arar. IEquatable<Foo> mutlaka Foo olmak zorunda olmadığından, orada neden belki başka tip en çok Equals(Foo f) aşırı seçmek için sağa (ya da olası) olmaz bu durumda IEquatable<Foo> uygulayan Bar, diyelim.

Derleyici IEquatable<Foo> temel türünü denetlemediğinden, Equals(Foo) aşırı yüklenmesini aramak için parametreyi açıkça Foo'a dökmeniz gerekir.

+0

Harika bir açıklama için teşekkürler. Bu tamamen mantıklı ve beni engelledi. – Tom19