• C#基础-事件 继承类无法直接引发基类的事件


    An event can be raised only from the declaration space in which it is declared. Therefore, a class cannot raise events from any other class, even one from which it is derived.

    事件只能在它被声明的声明空间(类)中使用。所以不能从任何其他类引发,即使该类是事件所在类的继承类。

    那我们如何才可以引发基类中的事件,给个实例大家一看就明白了。

    namespace BaseClassEvents
    {
        using System;
        using System.Collections.Generic;
    
        // Special EventArgs class to hold info about Shapes. 
        public class ShapeEventArgs : EventArgs
        {
            private double newArea;
    
            public ShapeEventArgs(double d)
            {
                newArea = d;
            }
            public double NewArea
            {
                get { return newArea; }
            }
        }
    
        // Base class event publisher 
        public abstract class Shape
        {
            protected double area;
    
            public double Area
            {
                get { return area; }
                set { area = value; }
            }
            // The event. Note that by using the generic EventHandler<T> event type 
            // we do not need to declare a separate delegate type. 
            public event EventHandler<ShapeEventArgs> ShapeChanged;
    
            public abstract void Draw();
    
            //The event-invoking method that derived classes can override. 
            protected virtual void OnShapeChanged(ShapeEventArgs e)
            {
                // Make a temporary copy of the event to avoid possibility of 
                // a race condition if the last subscriber unsubscribes 
                // immediately after the null check and before the event is raised.
                EventHandler<ShapeEventArgs> handler = ShapeChanged;
                if (handler != null)
                {
                    handler(this, e);
                }
            }
        }
    
        public class Circle : Shape
        {
            private double radius;
            public Circle(double d)
            {
                radius = d;
                area = 3.14 * radius * radius;
            }
            public void Update(double d)
            {
                radius = d;
                area = 3.14 * radius * radius;
                OnShapeChanged(new ShapeEventArgs(area));
            }
            protected override void OnShapeChanged(ShapeEventArgs e)
            {
                // Do any circle-specific processing here. 
    
                // Call the base class event invocation method. 
                base.OnShapeChanged(e);
            }
            public override void Draw()
            {
                Console.WriteLine("Drawing a circle");
            }
        }
    
        public class Rectangle : Shape
        {
            private double length;
            private double width;
            public Rectangle(double length, double width)
            {
                this.length = length;
                this.width = width;
                area = length * width;
            }
            public void Update(double length, double width)
            {
                this.length = length;
                this.width = width;
                area = length * width;
                OnShapeChanged(new ShapeEventArgs(area));
            }
            protected override void OnShapeChanged(ShapeEventArgs e)
            {
                // Do any rectangle-specific processing here. 
    
                // Call the base class event invocation method. 
                base.OnShapeChanged(e);
            }
            public override void Draw()
            {
                Console.WriteLine("Drawing a rectangle");
            }
    
        }
    
        // Represents the surface on which the shapes are drawn 
        // Subscribes to shape events so that it knows 
        // when to redraw a shape. 
        public class ShapeContainer
        {
            List<Shape> _list;
    
            public ShapeContainer()
            {
                _list = new List<Shape>();
            }
    
            public void AddShape(Shape s)
            {
                _list.Add(s);
                // Subscribe to the base class event.
                s.ShapeChanged += HandleShapeChanged;
            }
    
            // ...Other methods to draw, resize, etc. 
    
            private void HandleShapeChanged(object sender, ShapeEventArgs e)
            {
                Shape s = (Shape)sender;
    
                // Diagnostic message for demonstration purposes.
                Console.WriteLine("Received event. Shape area is now {0}", e.NewArea);
    
                // Redraw the shape here.
                s.Draw();
            }
        }
    
        class Test
        {
    
            static void Main(string[] args)
            {
                //Create the event publishers and subscriber
                Circle c1 = new Circle(54);
                Rectangle r1 = new Rectangle(12, 9);
                ShapeContainer sc = new ShapeContainer();
    
                // Add the shapes to the container.
                sc.AddShape(c1);
                sc.AddShape(r1);
    
                // Cause some events to be raised.
                c1.Update(57);
                r1.Update(7, 7);
    
                // Keep the console window open in debug mode.
                System.Console.WriteLine("Press any key to exit.");
                System.Console.ReadKey();
            }
        }
    }
    /* Output:
            Received event. Shape area is now 10201.86
            Drawing a circle
            Received event. Shape area is now 49
            Drawing a rectangle
     */

    参考

    How to: Raise Base Class Events in Derived Classes (C# Programming Guide)

  • 相关阅读:
    Servlet会话管理一(URL重写和表单隐藏域)
    Eclipse自动补全设置
    String类为什么设计成不可变的
    部署描述符(web.xml)和标注(annotation)
    html中 &nbsp; 和空格的区别
    HTML的基本知识点
    Eclipse中配置Tomcat服务器并创建标准Web目录
    Sevlet处理HTML表单
    Servlet API
    Servlet开发的三种方法
  • 原文地址:https://www.cnblogs.com/HQFZ/p/4238379.html
Copyright © 2020-2023  润新知