The problem is that the TabControl do this in an event handler of the ItemContainerGenerator’s StatusChanged event. This subscription is made in the OnInitialized method. This one is marked as protected and virtual so I could override it to do nothing but if had do so I would have loose all the work done in the base class of the TabControl which is Selector. So I needed to be able to call the Selector base method and skip the one of the TabControl. Unfortunately you can’t access to a method base class of the base class of your current instance.

 

In this post we’ll see how it can be performed anyway via a tricky technique. Truth to be told, I found this solution on stack overflow and I found it so neat that I needed to share it with you Smile !

Note: the title may be rephrased to “How to skip an override in a method inheritance path”.

Edit: thanks to Thomas Levesque there is now two solutions presented here !

 First solution

Let’s say that we have three classes : GrandFather, Father and Child.

inheritance

 

We want to be abble to call the MyMethod of the GrandFather from the MyMethod of the child without executing the body of the Father’s one. Each of this method only update the MyProperty method telling which method is executed. For example here is the body of the grandfather method:

public virtual void MyMethod(object param)
{
MyProperty = "I am set from the GrandFather class";
}

 

In the MyMethod of the Child, we usually call the base method using the base operator as in this snippet:

public override void MyMethod(object param)
{
base.MyMethod(param);
}

 

It works like a charm but in our case, what we actually need is to call base.base.MyMethod() but this is not possible in C#.

The solution is so to create a delegate, which, as Lassaad told me is a pointer to a function, and update it’s target to be our current instance. To create the delegate we need an instance of the GrandFather class so the aimed function is the good one on the grandFather class. Then we perform a little reflection magic to update the field of the Delegate representing its target so it become our current instance. Here is the snippet of code doing all this :

public override void MyMetdhod(object param)
{
//base.MyMethod(param); NO MORE !
//Create an instance of the grandFather
GrandFather grandFather = new GrandFather();
//Create a delegate to its "MyMethod" method
var createdDelegate = Delegate.CreateDelegate(
typeof(MyMethodDelegate),
grandFather,
"MyMethod"
);
//Change the target of the delegate to be the current instance
typeof(MyMethodDelegate).BaseType.BaseType.GetField(
"_target",
BindingFlags.Instance | BindingFlags.NonPublic)
.SetValue(createdDelegate, this);
//Invoke the delegate
createdDelegate.DynamicInvoke(param);
}

 

In the case of the TabControl it was even harder because the grand father class is Selector which is actually abstract and can’t be instanced. The solution is to create a “fake” class just for the purpose of this trick. It can then be used and instanced when needed:

 public class FakeClass : Selector { }

 

Here an example of this working in a WPF application (code source is attached):

working

Second solution

As pointed out by Thomas Levesque in the comments, the solution I first proposed have several drawbacks:

  1. We have to create an instance of the grand father class just to be abble to create the first delegate,
  2. We use reflection to set an undocumented field on the Delegate class which can disapear in the next version of the framework.

The solution he proposes is using the IL generator to create a dynamic method. This technique free us of the creation of a dummy instance which is better for performance and without side-effects... Here is the code to use in the Child class:
private delegate void MyMethodDelegate(GrandFather instance, object e);
private static readonly MyMethodDelegate myMethodDelegateRealMethod;

static Child() {     DynamicMethod dm = new DynamicMethod(         "GrandFatherMyMethod"typeof(void),        new Type[] { typeof(GrandFather), typeof(object) }, typeof(Child));     var il = dm.GetILGenerator();     il.Emit(OpCodes.Ldarg_0);     il.Emit(OpCodes.Ldarg_1);     il.EmitCall(OpCodes.Call, typeof(GrandFather)         .GetMethod("MyMethod"BindingFlags.Instance | BindingFlags.NonPublic), null);     il.Emit(OpCodes.Ret);     myMethodDelegateRealMethod=
(MyMethodDelegate)dm.CreateDelegate(typeof(MyMethodDelegate)); }

private override void MyMethod(EventArgs e) {     myMethodDelegateRealMethod(this, e);
}

Be sure to notice that this is the Call operator which is used instead of the CallVirt which would have result in an infinte call loop.

Don't forget to visit his blog : http://tomlev2.wordpress.com/



Shout it kick it on DotNetKicks.com