在子类的override方法中调用父类的父类的未被重写的方法

今天做一个自定义控件,扩展TableLayoutPanel这个控件加一些自己的属性,重写OnPaintBackground这个虚方法,

控件的继承关系是这样的:
Control
  ScrollableControl
    Panel
      TableLayoutPanel

这个虚方法在Control类中被定义,在ScrollableControl中被重写,在TableLayoutPanel中被又一次重写,
我自己的控件继承了TableLayoutPanel控件,因为TableLayoutPanel对OnPaintBackground方法重写时会进行对表格边框绘画,
而我仅仅需要给我画出背景,不需要边框,那么自然而然的想到下面的代码:

 1     public class BaseClass
 2     {
 3         protected int i { get; set; }
 4 
 5         protected virtual string GetString()
 6         {
 7             i = 1;
 8             return "BaseClass";
 9         }
10     }
11 
12     public class SubClass : BaseClass
13     {
14         protected override string GetString()
15         {
16             //return base.GetString();
17             base.i = 2;
18             return "SubClass";
19         }
20     }
21 
22     public class SubSubClass : SubClass
23     {
24         protected override string GetString()
25         {
26 
27             //want to call base.base.GetString
28             base.i = 3;
29             return "SubSubClass";
30         }
31     }
32 
33     public class MyClass : SubSubClass
34     {
35         protected override string GetString()
36         {
37 
38             MethodInfo miOnPaintBackground = typeof(SubClass).GetMethod(
39                                        "GetString",
40                                        BindingFlags.Instance | BindingFlags.NonPublic,
41                                        Type.DefaultBinder,
42                                        new Type[] { },
43                                        null);
44 
45 
46             object o = miOnPaintBackground.Invoke(this as SubClass, null);
47 
48             return (string)o;
49         }
50 
51         public string CallMethod()
52         {
53             return this.GetString();
54         }
55     }
56 
57     public class Program2
58     {
59         [STAThread]
60         static void Main()
61         {
62             MyClass m = new MyClass();
63 
64             string s = m.CallMethod();
65 
66             Console.WriteLine(s);
67 
68         }
69     }

很不幸,溢出了,是死循环,反射回来的并不是基类的基类的方法,而是我MyClass里面重写的方法。有请google大神出场,得到两篇文章:

http://stackoverflow.com/questions/4357729/use-reflection-to-invoke-an-overridden-base-method

http://blogs.msdn.com/b/rmbyers/archive/2008/08/16/invoking-a-virtual-method-non-virtually.aspx

我们改造下我自己的类:

 1     public class MyClass : SubSubClass
 2     {
 3         protected override string GetString()
 4         {
 5 
 6             MethodInfo miOnPaintBackground = typeof(SubClass).GetMethod(
 7                                        "GetString",
 8                                        BindingFlags.Instance | BindingFlags.NonPublic,
 9                                        Type.DefaultBinder,
10                                        new Type[] { },
11                                        null);
12 
13 
14 
15             var ftn = miOnPaintBackground.MethodHandle.GetFunctionPointer();
16             var func = (Func<string>)Activator.CreateInstance(typeof(Func<string>), this as SubClass, ftn);
17             string s = func();
18 
19             //object o = miOnPaintBackground.Invoke(this as SubClass, null);
20 
21             return s;
22         }
23 
24         public string CallMethod()
25         {
26             return this.GetString();
27         }
28     }

ok,得到我们先要的结果SubClass,越过了基类的重写,执行了基类的基类的protected override方法

posted @ 2013-04-18 22:58  BinSys  阅读(1802)  评论(2编辑  收藏  举报