Как я могу вызвать "базовую реализацию" переопределенного виртуального метода? [дубликат]
этот вопрос уже есть ответ здесь:
Есть ли способ вызвать родительскую версию переопределенного метода? (C# .NET)
8 ответов
учитывая следующий код, есть ли способ вызвать версию метода X класса A?
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...
}
6 ответов:
используя конструкции языка C#, вы не можете явно вызвать базовую функцию из за пределами объем
AилиB. Если вам действительно нужно это сделать, то в вашем дизайне есть недостаток - т. е. эта функция не должна быть виртуальной для начала, или часть базовой функции должна быть извлечена в отдельную невиртуальную функцию.вы можете внутри B. X однако вызовите A. X
class B : A { override void X() { base.X(); Console.WriteLine("y"); } }но это уже что-то еще.
как Саша 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().
Я konow это уже вопрос истории. Но для других гуглеров: вы могли бы написать что-то вроде этого. Но это требует изменения в базовом классе, что делает его бесполезным с внешними библиотеками.
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
Comments