在派生类中引发基类事件

1、  在创建基类时,若涉及到事件,事件是特殊类型的委托,只可以从声明它们的类中调用,派生类无法直接调用基类中声明的事件,但是在多数情况,会需要允许派生类调用基类事件,这时,可以再包含该事件的基类中创建一个受保护的虚调用方法,通过调用或重写此调用方法,派生类便可以间接调用该事件。

注:不要在基类中声明虚拟事件,也不要在派生类中重写这些事件,C#编译器无法正确处理这些事件,并且无法预知该派生的事件的用户是否真正订阅了基类事件。

和下面的程序示例都来自:https://msdn.microsoft.com/zh-cn/library/hy3sefw3.aspx

2、  插入知识点:virtual和abstract的区别:

virtual和abstract都是用来修饰父类的,通过覆盖父类的定义,让子类重新定义(子类方法前都必须添加override),因此虚拟方法和抽象方法都不能是私有的;

virtual修饰的方法必须有实现(哪怕是仅仅添加一对大括号),而abstract修饰的方法一定不能实现;

 virtual可以被子类重写,而abstract必须被子类重写;

如果类成员被abstract修饰,则该类前必须添加abstract,因为只有抽象类才可以有抽象方法;

无法创建abstract类的实例;

3、示例程序

  1 namespace Test0301
  2 {
  3     class Program
  4     {
  5         static void Main(string[] args)
  6         {
  7             Circle c1 = new Circle(7);
  8             Rectangle r1 = new Rectangle(12, 9);
  9             ShapeContainer sc = new ShapeContainer();
 10 
 11             sc.AddShape(c1);
 12             sc.AddShape(r1);
 13 
 14             c1.Update(1);
 15             r1.Update(7, 7);
 16 
 17             Console.WriteLine("Press any key to ecit...");
 18             Console.ReadKey();
 19         }
 20     }
 21 
 22     public class ShapeEventArgs : EventArgs
 23     {
 24         private double newArea;
 25 
 26         public ShapeEventArgs(double d)
 27         {
 28             newArea = d;
 29         }
 30 
 31         public double NewArea
 32         {
 33             get { return newArea; }
 34         }
 35     }
 36 
 37     public abstract class Shape
 38     {
 39         protected double area;
 40 
 41         public double Area
 42         {
 43             get { return area; }
 44             set { area = value; }
 45         }
 46 
 47         public event EventHandler<ShapeEventArgs> ShapeChanged;
 48 
 49         public abstract void Draw();//abstract和类定义的abstract对应,在派生类中必须实现
 50 
 51         //基类可以重载此函数,实现实际对象类型的此函数
 52         //此函数为事件句柄的实现函数
 53         protected virtual void OnShapeChanged(ShapeEventArgs e) 
 54         {
 55             Console.WriteLine("基类事件处理函数被{0}调用", this.ToString());
 56 
 57             EventHandler<ShapeEventArgs> handler = ShapeChanged;
 58             if (handler != null)
 59             {
 60                 handler(this, e); //this为调用此函数的派生类对象
 61             }
 62         }
 63     }
 64 
 65     public class Circle : Shape
 66     {
 67         private double radius;
 68 
 69         public Circle(double d)
 70         {
 71             radius = d;
 72             area = 3.14 * radius * radius;
 73         }
 74 
 75         public void Update(double d)
 76         {
 77             radius = d;
 78             area = 3.14 * radius * radius;
 79             OnShapeChanged(new ShapeEventArgs(area));
 80         }
 81 
 82         protected override void OnShapeChanged(ShapeEventArgs e)
 83         {
 84             //具体类的处理
 85             Console.WriteLine("Circle's radius changed!");
 86 
 87             //调用基类的函数
 88             base.OnShapeChanged(e);
 89         }
 90 
 91         public override void Draw()
 92         {
 93             Console.WriteLine("Drawing a circle");
 94             Console.WriteLine();
 95         }
 96     }
 97 
 98     public class Rectangle : Shape
 99     {
100         private double length;
101         private double width;
102 
103         public Rectangle(double length,double width)
104         {
105             this.length = length;
106             this.width = width;
107             area = length * width;
108         }
109 
110         public void Update(double length, double width)
111         {
112             this.length = length;
113             this.width = width;
114             area = length * width;
115             OnShapeChanged(new ShapeEventArgs(area));
116         }
117 
118         protected override void OnShapeChanged(ShapeEventArgs e)
119         {
120             Console.WriteLine("Rectangle's radius changed!");
121             base.OnShapeChanged(e);
122         }
123 
124         public override void Draw()
125         {
126             Console.WriteLine("Drawing a rectangle!");
127             Console.WriteLine();
128         }
129     }
130 
131     public class ShapeContainer
132     {
133         List<Shape> _list;
134 
135         public ShapeContainer()
136         {
137             _list = new List<Shape>();
138         }
139 
140         public void AddShape(Shape s)
141         {
142             _list.Add(s);
143             //订阅基类事件
144             s.ShapeChanged += HandleShapeChanged;
145         }
146 
147         private void HandleShapeChanged(object sender, ShapeEventArgs e)
148         {
149             Shape s = (Shape)sender;
150 
151             Console.WriteLine("Receicved event,Shape area is now {0}", e.NewArea);
152 
153             s.Draw();
154         }
155     }
156 }
原文地址:https://www.cnblogs.com/xyl-share-happy/p/4307400.html