Is there a way to specify an area?

Consider this code example:

public abstract class Parent { public int val; public Parent() { val = 0; } public virtual void foo() { inc(); } public virtual void inc() { val = val + 10; } } public class Child : Parent { public override void foo() { base.foo(); } public override void inc() { val++; } } static void Main(string[] args) { Parent p = new Child(); Console.WriteLine("p.val = " + p.val); //Output: p.val = 0 p.foo(); Console.WriteLine("P.val = " + p.val); //Output: p.val = 1 } 

I assume that the inc() of the Parent class did not receive the call because the {this} pointer actually points to the Child object, so the child version of inc() will be called from the function of the parent object foo() inc() . Is there a way to force the parent function foo() always call the parent function inc() How could you do in C ++ with the :: operator?

+4
source share
4 answers

You changed your mind about the problem.

  • If you want non-virtual dispatch, then do not do virtual methods in the first place.

  • If you want both virtual and non-virtual sending, follow two methods: one virtual and one static

For instance:

 class Base { protected static void NonVirtualFoo(Base b) { // Whatever } public virtual void Foo() { Base.NonVirtualFoo(this); } } class Derived : Base { protected new static void NonVirtualFoo(Derived d) { // Whatever } public override void Foo() { Derived.NonVirtualFoo(this); Base.NonVirtualFoo(this); } } 

Use the right tool for the job. If you want a virtual dispatch, then call the virtual method . If you want a static dispatch, then call the static method . Do not try to take a hammer on a virtual method and make it statically dispatched; what works against the whole purpose of the tool.

+6
source

No, the only virtual method you can call virtual is base.Foo . Of course, you can write a non-virtual method in Parent and make a call to Parent.foo() , as well as the default implementation of Parent.inc() .

+7
source

An instance of Child will invoke an implementation of its type.

foo() calls base.foo() and base.foo() calls inc() , which in this case inc() refers to the Child, since the instance is of type Child and will use this implementation.

+1
source

Well, it is actually possible as said here :

This is the trick:

 public abstract class Parent { public int val; public Parent() { val = 0; } public virtual void foo() { MethodInfo method = typeof(Parent).GetMethod("inc"); DynamicMethod dm = new DynamicMethod("BaseInc", null, new Type[] { typeof(Parent) }, typeof(Parent)); ILGenerator gen = dm.GetILGenerator(); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Call, method); gen.Emit(OpCodes.Ret); var BaseInc = (Action<Parent>)dm.CreateDelegate(typeof(Action<Parent>)); BaseInc(this); } public virtual void inc() { val = val + 10; } } 

But this is only a proof of the concept: it is terrible and completely destroys polymorphism .

I don’t think you have a good reason to write this.

0
source

Source: https://habr.com/ru/post/1397790/


All Articles