2014-06-23 3 views
2

C#에서 메서드 숨기기 및 재정의에 대한 몇 가지 자습서 (MSDN 웹 사이트의 자습서 포함)를 읽었으며 코드 조각에서 문제를 발견했습니다. 쓴 논리를 이해하는 동안 : 그 코드를 실행할 때마다C에서 가상 메서드, 메서드 숨기기 및 재정의 이해

class A 
{ 
    public virtual void Foo() 
    { 
     Console.WriteLine("A"); 
    } 
} 

class B : A 
{ 
    public override void Foo() 
    { 
     Console.WriteLine("B"); 
    } 
} 

class C : B 
{ 
    new public virtual void Foo() 
    { 
     Console.WriteLine("C"); 
    } 
} 
class Driver 
{ 
    static void Main() 
    { 
     A a = new A(); 
     a.Foo(); 
     B b = new B(); 
     b.Foo(); 
     C c = new C(); 
     c.Foo(); 
     a = new B(); 
     a.Foo(); 
     a = new C(); 
     a.Foo(); 
     Console.ReadKey(); 
    } 
} 

내가이 출력 얻을 : B C B B를

처음 네 개를 이해하고 있지만 실행 인스턴스가 C이고 A가 아니기 때문에 다섯 번째 출력이 'C'가 아니어야합니까? 클래스 C에서 "public virtual void Foo()"를 선언해서는 안되며 B에서 파생 된 Foo()를 대신 호출 할 수 있습니다.

+2

합니다. '가상'은 당신이 무시하는 것을 의미합니다; 'new'는 당신이 그림자를 가지고 있음을 의미합니다. –

+0

@ RobertHarvey 나는 그렇게 생각하지 않았다. 어쩌면 그냥 경고하는거야? Zach에; 그것이 숨어서하는 것입니다. –

+0

메서드 재정의 및 숨기기에 대해 읽었습니다. 마지막 사건은 숨어 있습니다. 그게 말이 되니? – usr

답변

3

다섯 번째 출력이 B인데, C 인스턴스가 A 인스턴스 인 것처럼 보이므로 여기가 메소드 디스패치 시작 부분입니다.

A.Foo에서 상속 체인으로 올라가서 B.FooC.Foo을 확인합니다. C.Foonew 수정 자로 표시되기 때문에 B.Foo이 실제로 호출됩니다.

당신은 다음 코드에 대한 출력으로 C를 얻을 것 : 당신은 같은 시간에`new`와`virtual`를 사용할 수 있다고 생각하지 않습니다

C c = new C(); 
c.Foo(); 
+0

다섯 번째 출력은 C가 아닙니다. B입니다. A instance = new C();를 수행했을 때와 같을 것입니다. –

+0

@DanielMay 물론 당신 말이 맞습니다. 그냥 오타 야. – MarcinJuraszek