2011-08-09 9 views
2
public class A 
{ 
    ... 
    public virtual void PrintMe() { /* do A */ } 
} 

public class B : A 
{ 
    ... 
    public override void PrintMe() { /* do B */ } 
} 

public class C : B 
{ 
    ... 
    public override void PrintMe() { /* do C */ } 

    private void Fun() 
    { 
     // call C::PrintMe - part one 
     PrintMe(); 

     // call B::PrintMe - part two 
     base.PrintMe(); 

     // call A::PrintMe - part three 
     ??? 
    } 
} 
  1. はパート2のコードは正しいですか?コール基底クラスのメンバ関数

  2. A::PrintMeC::Funに電話するにはどうすればいいですか?

+3

が重複する可能性をbase.base.GetHashCode()](http://stackoverflow.com/questions/1006530/c-how-to-call-a-second-level-base-class-method-like-base-base-gethashcode) –

答えて

0

あなたは、この目的の機能が必要な場合は、あなたのBクラスでbase.PrintMe()を呼び出すことができます。

public class B : A 
{ 
    public override void PrintMe() 
    { 
    /* do B */ 
    base.PrintMe(); 
    } 
} 

そうしないと、あなたはハック何かに頼ることなく、クラスAから実装を呼び出すことはできません。予想通り、あなたの質問1が動作する

+0

これは私の質問ではありません。 – q0987

2

、それはB.PrintMe()

あなたの質問2はそれほど単純ではないでしょう。 A.PrintMe()を実行する暗黙的または明示的な方法はありません。

あなたの目標を達成するために考えられる唯一の方法は、Cから呼び出すことができるAの保護されたメソッドを追加することです。

public class A 
{ 
    protected void BasePrintMe() { Console.WriteLine("A"); } 
    public virtual void PrintMe() { BasePrintMe(); } 
} 

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

public class C : B 
{ 
    public override void PrintMe() { Console.WriteLine("C"); } 

    public void FunA() 
    { 
     // call C::PrintMe - part one 
     PrintMe(); 

     // call B::PrintMe - part two 
     base.PrintMe(); 

     // call A 
     this.BasePrintMe(); 

    } 

} 

出力:

C 
B 
A 
+0

ちょうど覚えておいてください。 - BasePrintMe()と呼ばれる 'B'にメソッドを作成しないでください。あるいは、その実装は' C'から呼び出されます。 –

0

あなたはbase.PrintMe()を行うだろう、各クラスにメソッドを追加することができます。 Aでは、このメソッドは基本クラスを持たないため何も行いません。

public class A 
    { 
     public virtual void PrintMe() 
     { 
     Debug.WriteLine("PrintMe: A"); 
     } 

     public virtual void PrintMyBase() 
     { 
     } 
    } 

    public class B : A 
    { 
     public override void PrintMe() 
     { 
     Debug.WriteLine("PrintMe: B"); 
     } 

     public override void PrintMyBase() 
     { 
     base.PrintMe(); 
     } 
    } 

    public class C : B 
    { 
     public override void PrintMe() 
     { 
     Debug.WriteLine("PrintMe: C"); 
     } 

     public override void PrintMyBase() 
     { 
     base.PrintMe(); 
     } 

     private void Fun() 
     { 
     // call C::PrintMe - part one 
     PrintMe(); 

     // call B::PrintMe - part two 
     PrintMyBase(); 

     // call A::PrintMe - part three 
     base.PrintMyBase(); 
     } 
    } 

ここBEFITは何のクラスは、それのベースクラス以上のものを知らなければならないと私たちは継承チェーンを下にさらさ何を制御できるということです。

希望これは、あなたがそれを行うべきではないことを示唆するための便利なヒントですこれを行うことのない言語サポートされている方法は、ありません

-1

に役立ちます。

実際のコードでこれが必要な場合は、実際にデザインを再考する必要があります。とにかく

、質問に答えるために、あなたはそのような本用いた反射といくつかのカスタムIL-世代、行うことができますどのようにセカンドレベル基底クラスのメソッドを呼びたい:[C#2の

private void Fun() 
{ 
    // call C::PrintMe - part one 
    PrintMe(); 

    // call B::PrintMe - part two 
    base.PrintMe(); 

    // call A::PrintMe - part three 
    MethodInfo mi = this.GetType().GetMethod("PrintMe").GetBaseDefinition(); 

    var dm = new DynamicMethod("dm", null, new[] { typeof(object) }, this.GetType()); 

    ILGenerator il = dm.GetILGenerator(); 
    il.Emit(OpCodes.Ldarg_0); 
    il.Emit(OpCodes.Call, mi); // use call rather than callvirt 
    il.Emit(OpCodes.Ret); 

    var action = (Action<object>)dm.CreateDelegate(typeof(Action<object>)); 
    action(this); 
} 
関連する問題