この質問にはすでに答えがあります。
次のコードで、クラス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#言語の構成要素を使用して、から基本関数を明示的に呼び出すことはできません。外側の範囲A
またはB
。あなたが本当にそれをする必要があるならば、それからあなたの設計に欠陥があります - すなわちその機能は最初は仮想であるべきではないか、またはベース機能の一部は別の非仮想機能に抽出されるべきです。
からすることができます内部B.XしかしA.Xを呼び出す
class B : A
{
override void X() {
base.X();
Console.WriteLine("y");
}
}
しかしそれは別のことです。
Sasha Trufが指摘するようにこの答え、あなたはILを介してそれを行うことができます。 mhandがコメントで指摘しているように、あなたはおそらく反射を通してそれを達成することもできます。
C#ではできませんが、MSILは編集できます。
あなたの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のオペコードはCallvirtにコール
L_0008: call instance void MsilEditing.A::X()
できません、できません。それがポリモーフィズムの目的であり、各オブジェクトは独自の方法で「基本」のことを実行します。
できますが、指定した時点ではできません。のコンテキスト内でB
、あなたが呼び出すことができますA.X()
電話でbase.X()
。
私は今、歴史の問題だと知っています。しかし、他のグーグルにとっては:あなたはこのようなものを書くことができます。しかし、これには基本クラスの変更が必要であり、外部ライブラリでは使用できなくなります。
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