2012-07-04 16 views
6

Sanal bir üyeyi yapıcıda çağırmanın etkilerini test ediyordum ve bu üye çağırılırken, sonuç istisnasının bir TargetInvocationException içine sarıldığını keşfettim.Sanal üyeler yansıma yoluyla çağrılıyor mu (normal şartlarda)?

docs göre şudur: yansıması

içinden çağrılan yöntemlerle atılır

istisna Ancak yansıma yoluyla herhangi invokations habersiz değilim. Yani bu ortalama sanal üyelere her zaman yansıma aracılığıyla çağrılıyor? Eğer bu durumda neden olmasın?

kodu:

class ClassA 
    { 
     public ClassA() 
     { 
      SplitTheWords(); 
     } 

     public virtual void SplitTheWords() 
     { 
      //I've been overidden 
     } 
    } 

class ClassB : ClassA 
    { 
     private readonly String _output; 

     public ClassB() 
     { 
      _output = "Constructor has occured"; 
     } 

     public override void SplitTheWords() 
     { 
      String[] something = _output.Split(new[]{' '}); //TargetInvocationException! 
     } 
    } 

cevap

5

Hayır, sanal metotlar virtual dispatch aracılığıyla denir.

Yansıma burada kullanılmıyor. Ve herhangi bir sanal yöntem çağrısı için de değildir. Bu tür istisnalar istisnasıyla ilgili belgelerin biraz yanıltıcı olduğuna inanıyorum, bu tip istisnaları, yansıma yoluyla çağrılan yöntemlerle atılan, ancak özel olarak değil. Herkes söz konusu kod bir istisna verir neden olarak meraklı ise

bunun nedeni kurucular infaz sırayla taşımaktadır. base() çağrısı, bu nedenle, _output önce atanır ClassB yapıcı çalıştırılır önce temel kurucu çağırır ve

public ClassB() : base() 
{ 
    _output = "Constructor has occured"; 
} 

Not: ClassB yapıcı aynıdır. SplitTheWords sanal yöntemi, ClassB.SplitTheWords'a dönüşen temel yapıcıda çağrılır. Bu yöntem, _output kullanmayı deniyor, dolayısıyla hata. Sanal yöntemler kurucular this SO question çağrılabilir edilmemelidir neden daha ayrıntılı bir görünüm için

bazı yararlı bilgiler. Eric Lippert'in, bunun neden here olduğunu açıklayan çok iyi bir blog yazısı var. "Biraz yanıltıcı" için

+1

1, yani dokümanlar söylemek için derin kafa karıştırıcı bir şey. Yeni TargetInvocationException() 'ı atmak dışında hiçbir şey yapmayan bir konsol uygulaması yazılabilir: - o zaman yansıma nerede olur? – AakashM

+0

_Why_ sanal üyelerinin kuruculardan çağrılmamasını anlıyorum, bu beni denememi sağlayan şey budur –

+0

@ m.edmondson Özür dilerim, bunu 'Sizin etkilerini test ediyordum' hakkındaki satırınızdan anladım. Cevabımın küçümseyici olmasını istemedim (ama şimdi olabileceğini düşünüyorum), bu cevabı gören diğer kişiler için sadece son birkaç paragrafı tamamladım. Tekrar ifade etmeye çalışacağım. –

0

sanal üyeler (normal koşullarda) yansıma yoluyla denilen mı?

NO.

Ne de kurucusundan

, başka öylesine bir şey oluyor. Gösterdiğiniz kodu çağıran kodun ve istisnadan yığın izinin görülmesine yardımcı olur.

İlgili konular