2010-09-05 23 views
9
class Base 
{ 
    public virtual void MethodA(int x) 
    { 
     Console.WriteLine ("In Base Class"); 
    } 
} 

class Derived : Base 
{ 
    public override void MethodA(int x) 
    { 
     Console.WriteLine ("In derived INT)"); 
    } 

    public void MethodA(object o) 
    { 
     Console.WriteLine ("In derived OBJECT"); 
    } 
} 

class Test 
{ 
    static void Main() 
    { 
     Derived d = new Derived(); 
     int k = 20; 
     d.MethodA(k); 
    } 
} 

Bunun için aldığım çıkış "Türetilmiş OBJECT" dir. Bu garip davranışın sebebi nedir? Bazı araştırmalardan sonra, nedeninin taban sınıfında bildirilen imzaların göz ardı edildiğini öğrendim. Neden göz ardı ediliyorlar?Temel sınıfta bildirilen imzalar neden yok sayılıyor?

+1

+1 soruya, bu sezgilere davranıştır katılıyorum. –

+0

Davranışın garip olduğunu kabul ediyorum. Bilmek isterim: Bunu soruyor musunuz, çünkü bunu yapmak istersiniz, yoksa merak ettiğiniz için mi? Böyle bir şeyi gerçekte uygulamak için bir neden göremiyorum, ama neden olduğunu bilmek isterdim. –

+0

olası kopyası [C# yöntem gizleme nasıl çalışır? (İkinci Bölüm)] (http://stackoverflow.com/questions/710459/how-method-hiding-works-in-c-part-two) –

cevap

6

Bu tasarım ve iyi bir nedenden kaynaklanmaktadır. Bu tasarım, Gevrek Temel Sınıf problemini önlemeye yardımcı olur. C# "sürüm" bileşenlerini yazmayı daha kolay ve daha güvenli hale getirmek için tasarlandı ve bu kural bunun büyük bir kısmı.

Bu çok sık sorulan bir sorudur. Bu, aldığımız en yaygın "yanlış hata raporlarından" biridir; Yani, birisi aslında bir özellik bulduklarında derleyicide bir hata bulduklarına inanıyor.

özelliğin açıklaması için

ve bu haliyle tasarlanmıştır neden konuyla ilgili benim makalesine bakın: Gevrek ile nasıl başa çeşitli diller konusunda daha fazla makaleler için

http://blogs.msdn.com/b/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx

Temel Sınıf sorun konudaki makalelerin Arşivimi bkz:

http://blogs.msdn.com/b/ericlippert/archive/tags/brittle+base+classes/

2

VC# da derleyici 2008 denetler sanal olanlar, önce mevcut olmayan sanal fonksiyonlar aramaya karar vermektir. Türetilmiş sınıfınız, çağrılabilen sanal olmayan bir MethodA (nesne) içerdiğinden, derleyici bunu çağırır.

Bir MethodA (object) nesnesine Base eklerseniz, o zaman Derived.MethodA (int) çağrılır, çünkü her ikisi de MethodA (object) ve MethodA (int) sanaltır.

Ben bu davranışı, veya derleyici bir hata belirtilir olmadığını bilmek C# dili spec ile yeterince aşina değilim.

+0

Gerçekten de ECMA spesifikasyonlarında, sanal olmayanlar önce çağrılır. Ayrıca çağrılan yöntem sanal olmayan yöntemler için derleyici tarafından belirlenir ve sanal yöntemler için çalışma zamanı türüne göre belirlenir. –

+0

Bunu kontrol ettim, ancak Derived.MethodA (int) 'nin sadece' geçersiz kıl 'anahtar sözcüğünü Derived.MethodA (object)' a eklediğinizde (tabii ki bu demek oluyordu) çağrılacağına dikkat edin. Bu olmadan 'yeni' anahtar kelimesi kabul edilir ve Derived.MethodA (nesne) çağrılır. – Gerard

İlgili konular