2017-10-27 2 views
0

자식 클래스에서 기본 클래스를 직접 호출하여 파생 클래스에 대해 정의 된 확장 메서드를 호출 할 수없는 이유는 무엇입니까 (기본 클래스에서 컴파일 오류가 발생하지 않습니다. 확장 메서드의 정의를 포함한다). 대신 아이 Intance에서 직접 호출 할 때 컴파일 오류없이 확장 메서드를 호출 할 수 있습니다. 당신은 확장 메서드를 호출 할 때하위 클래스의 기본 클래스 확장 메서드 호출

using System; 
using System.Reflection; 

    public class Program 
    { 
     public static void Main() 
     { 
     Child child = new Child(); 
     child.TestMethod(); 
     } 
    } 

    // Derived class 
    public class Mother 
    { 

    } 

    // Child class 
    public class Child : Mother 
    { 
    public Child() : base() 
    { 
    } 

    public void TestMethod() 
    { 
     this.ExtentionMethod(3);// Ok: no compile errors 
     base.ExtentionMethod(3);// Ko: Compilation error (line 27, col 8): 'Mother' does not contain a definition for 'ExtentionMethod' 
    } 
} 

public static class Extender 
{ 
    public static void ExtentionMethod(this Mother mother, int i) 
    { 
    Console.WriteLine($"Mother extention method {i}"); 
    } 

} 
+0

왜 '* base.ExtentionMethod (3)'를 호출할까요? 그것은 정확히 this.ExtentionMethod (3)과 동일합니다. 이것은 예제가 이미 작동하는 것처럼 보여줍니다. –

+0

@BradleyUffner 내가 알기에 호기심에 의해 기본 클래스에서 호출하는 것이 불가능한 이유를 알고 싶습니다. –

+0

그 행동을 원할 수있는 유일한 시간은 'Child '버전처럼,'public static void ExtentionMethod (이 자식 child, int i) {}'처럼, @DStanley가 준 응답 에서처럼, 호출하기 전에'this'를'Mother'에 캐스트 할 것입니다. –

답변

3

이 컴파일러는 왼쪽에있는 참조의 종류를 살펴보고 가장 적절한 방법을 찾습니다 다음은 내 질문에 대한 코드입니다. 따라서 this.ExtentionMethod으로 전화 할 때 가장 좋은 방법을 찾으려면 this 유형을 사용하십시오.

따라서 귀하의 경우 컴파일러는 Child 첫 번째 매개 변수가있는 확장명을 찾습니다. 따라서 하나가 없으므로 첫 번째 매개 변수 (Child "is-a"이므로 Mother)를 찾습니다.

base을 사용하면 캐스트를 수행하지 않으며 기본 클래스의 멤버에 액세스하는 데 사용됩니다. 확장 메서드가 "멤버"가 아니기 때문에 base은 예상 한대로 수행하지 않습니다.

((Mother)this).ExtentionMethod(3); 

것은 내가 무엇을 가진, 그래서 당신이 파생 클래스의 다른 확장 방법이없는 점에 유의 것이지만 : 대신 기본 클래스에this 캐스트에

대안이 될 수 당신은 this.ExtensionMethod((Mother)this).ExtensionBethod 사이에 아무런 차이가 없을 것이라고 게시했습니다. 동일한 메소드 (동일한 입력 값)가 호출됩니다.

+0

답장을 주신 @ Stanley, 확장 메서드는 정의 된 클래스의 멤버가 아니며 base 키워드는 파생 클래스의 인스턴스가 아니라 파생 클래스 멤버를 가져 오는 것을 의미합니다. –

0

이 확장은 D Stanley's answer입니다.

에게이 같은 모두MotherChild에 확장 방법이 있다면 :

public static class Extender 
{ 
    public static void ExtentionMethod(this Mother mother, int i) 
    { 
     Console.WriteLine($"Mother extention method {i}"); 
    } 

    public static void ExtentionMethod(this Child child, int i) 
    { 
     Console.WriteLine($"Child extention method {i}"); 
    } 
} 

그런 다음 기본 클래스 대 하위 클래스에서 호출 구별이있다. Child

this.ExtentionMethod(3); 

내부에서

Child 버전을 호출합니다.


((Mother)this).ExtentionMethod(3); 

Mother 버전을 호출합니다.

아동 확장자 방법은 3
어머니의 확장자 방법은 3

0

다른 답변을 아주 좋은 제안 :


public void TestMethod() 
{ 
    this.ExtentionMethod(3); 
    ((Mother)this).ExtentionMethod(3); 
} 

는 위에서 확장 방법 모두 다음과 같은 출력을 생성겠습니까 설명 당신은 문제가 있습니다, 나는 sur를 만들고 싶습니다. 전자 당신은 혼란에서 가장 빠른 방법을 알고 컴파일러는 확장 메서드를 인식하지 못하는 경우

public void TestMethod() 
{ 
    this.ExtentionMethod(3); 
    Extender.ExtentionMethod((Mother)this, 3); 
} 

, 단지 구문 설탕을 제거합니다. 확장 메서드에 대한 키워드가 없었던 것처럼 일반 공용 정적 메서드와 마찬가지로 매개 변수를 전달하고 호출 할 수 있습니다. 그것은 어느 쪽이든 아니거나, 여전히 옛날 방식으로 갈 수 있습니다.

+0

코드가 컴파일되지 않습니다. 인수로'base'를 사용할 수 없습니다. bace 회원을 만날 수있는 키워드. –

+0

@DStanley 하, 맞습니다. 전달되는 실제 객체에 실제로주의를 기울이지 않았고 정상적인 구문을 사용하는 것이 더 쉬운 많은 기발한 상황이 있습니다. – nvoigt

관련 문제