Development Tip

재정의 된 가상 메서드의 '기본 구현'을 어떻게 호출 할 수 있습니까?

yourdevel 2020. 11. 7. 10:35
반응형

재정의 된 가상 메서드의 '기본 구현'을 어떻게 호출 할 수 있습니까?


다음 코드가 주어지면 클래스 A 버전의 메서드 X를 호출 할 수있는 방법이 있습니까?

class A
{
  virtual void X() { Console.WriteLine("x"); }
}

class B : A
{
  override void X() { Console.WriteLine("y"); }
}

class Program
{
  static void Main()
  {
    A b = new B();
    // Call A.X somehow, not B.X...
  }

C # 언어 구문을 사용하면 또는 범위 외부 에서 기본 함수를 명시 적으로 호출 할 수 없습니다 . 정말로 그렇게해야한다면, 디자인에 결함이있는 것입니다. 즉, 그 함수는 처음부터 가상이 아니거나 기본 함수의 일부를 별도의 비가 상 함수로 추출해야합니다.AB

BX 내부 에서 가능 하지만 AX를 호출하십시오.

class B : A
{
  override void X() { 
    base.X();
    Console.WriteLine("y"); 
  }
}

그러나 그것은 다른 것입니다.

Sasha Truf 가이 답변 에서 지적했듯이 IL을 통해 할 수 있습니다. mhand가 주석에서 지적했듯이 반성을 통해 그것을 달성 할 수도 있습니다.


C #으로는 할 수 없지만 MSIL은 편집 할 수 있습니다.

Main 메서드 의 IL 코드 :

.method private hidebysig static void Main() cil managed
{
    .entrypoint
    .maxstack 1
    .locals init (
        [0] class MsilEditing.A a)
    L_0000: nop 
    L_0001: newobj instance void MsilEditing.B::.ctor()
    L_0006: stloc.0 
    L_0007: ldloc.0 
    L_0008: callvirt instance void MsilEditing.A::X()
    L_000d: nop 
    L_000e: ret 
}

L_0008의 opcode를 callvirt 에서 call로 변경해야합니다.

L_0008: call instance void MsilEditing.A::X()

할 수는 있지만 지정한 시점에서는 할 수 없습니다. 의 컨텍스트 내에서를 B호출 A.X()하여 호출 할 수 있습니다 base.X().


당신은 할 수없고,해서는 안됩니다. 그것이 다형성을위한 것입니다. 그래서 각 개체는 몇 가지 "기본"작업을 수행하는 고유 한 방법을 갖습니다.


나는 지금 그것이 역사 문제라는 것을 알고 있습니다. 그러나 다른 Google 사용자에게는 다음과 같이 작성할 수 있습니다. 그러나 이것은 외부 라이브러리에서 쓸모 없게 만드는 기본 클래스의 변경이 필요합니다.

class A
{
  void protoX() { Console.WriteLine("x"); }
  virtual void X() { protoX(); }
}

class B : A
{
  override void X() { Console.WriteLine("y"); }
}

class Program
{
  static void Main()
  {
    A b = new B();
    // Call A.X somehow, not B.X...
    b.protoX();


  }

메서드가 파생 클래스에서 overrides. 그렇게하려면 파생 클래스의 메서드를 다음과 같이 선언해야합니다 new.

public class Base {

    public virtual string X() {
        return "Base";
    }
}
public class Derived1 : Base
{
    public new string X()
    {
        return "Derived 1";
    }
}

public class Derived2 : Base 
{
    public override string X() {
        return "Derived 2";
    }
}

Derived1 a = new Derived1();
Base b = new Derived1();
Base c = new Derived2();
a.X(); // returns Derived 1
b.X(); // returns Base
c.X(); // returns Derived 2

여기에서 바이올린 참조

참고 URL : https://stackoverflow.com/questions/1334254/how-can-i-call-the-base-implementation-of-an-overridden-virtual-method

반응형