zoukankan      html  css  js  c++  java
  • 在子类的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方法

  • 相关阅读:
    css选择符有哪些?哪些属性可以继承?优先级算法如何计算?内联和important哪个优先
    移动端重要的几个CSS3属性设置
    关于移动端的Click事件
    JS根据key值获取URL中的参数值,以及把URL的参数转换成json对象
    动态添加JS文件到页面
    JS 模拟C# 字符串格式化操作
    JS cookie 读写操作
    很好用的Tab标签切换功能,延迟Tab切换。
    SpringMVC 原理
    SpringMVC 三种异常处理方式
  • 原文地址:https://www.cnblogs.com/binsys/p/3029733.html
Copyright © 2011-2022 走看看