C# 高级知识 事件的标准用法

来源:互联网 发布:unity3d 四元数 编辑:程序博客网 时间:2024/06/16 11:19

事件的标准用法1

    class Program
    {
        static void Main(string[] args)
        {
            HasEvent hasEvent = new HasEvent();
            hasEvent.myEvent += has_SampleEvent;

            hasEvent.OnRaiseEvent("work smart");
            hasEvent.OnRaiseEvent("work hard");


            Console.ReadKey();
        }

                 /// <summary>
                 /// 事件响应方法
                 /// </summary>
                 /// <param name="sender">
事件源</param>
                 /// <param name="e">
事件参数</param>     

        static void has_SampleEvent(object sender, MyEventArgs e)
        {
            Console.WriteLine(e.Msg);
        }
    }

    //声明一个继承自System.EventArgs的类,用于传递事件参数
    public class MyEventArgs : EventArgs
    {
        public MyEventArgs(string str)
        {
            msg = str;
        }

        private string msg;

        public string Msg
        {
            get { return msg; }
            set { msg = value; }
        }
    }


        /// <summary>
        /// 事件发布类
        /// </summary>

    public class HasEvent
    {
        //使用Event关键字定义一个事件
        public event EventHandler<MyEventArgs> myEvent;

        //事件标准模式还需要些一个受保护的虚方法来触发事件,这个方法必须以On为前缀,加上事件名

       //激发事件
        public void OnRaiseEvent(string str)
        {
            if (myEvent != null)
            {
                myEvent(this, new MyEventArgs(str));
            }
        }
    }

===================================================================================


事件的标准用法2

    class Program
    {
        static void Main(string[] args)
        {
            Apple ap1 = new Apple(){
               Preice = 5288
            };


            //注册事件
            ap1.myEvent += PriceChanged;


            //调整价格,触发事件
            ap1.Preice = 3999;


            Console.ReadKey();
        }
        

        //事件响应程序
        static void PriceChanged(object sender, MyEventArgs e)
        {
             Console.WriteLine("年终大促销,iPhone 6 只卖 " + e.NewPrice + " 元, 原价 " + e.OldPrice + " 元,快来抢!");
        }
    }


    /// <summary>
    /// 事件参数类
    /// </summary>
    public class MyEventArgs : EventArgs
    {
        public MyEventArgs(decimal newPrice, decimal oldPrice)
        {
            this.NewPrice = newPrice;
            this.OldPrice = oldPrice;
        }


        public readonly decimal NewPrice;
        public readonly decimal OldPrice;
    }


    /// <summary>
    /// 事件发布者类
    /// </summary>
    public class Apple
    {
        private decimal price;


        public decimal Preice
        {
            get
            {
                return price;
            }
            set
            {
                //如果价格变了,触发事件通知用户价格变了
                if (price == value)
                {
                    return;
                }


                decimal oldPrice = price;
                price = value;

                //激发事件
                OnRaiseEvet(new MyEventArgs(price, oldPrice));
            }
        }

        
        public event EventHandler<MyEventArgs> myEvent;

        
        public virtual void OnRaiseEvet(MyEventArgs e)
        {

            //如果调用列表不为空,则触发
            if (myEvent != null)
            {
                myEvent(this, e);

               //event关键字定义的事件只能由事件源对象自己激发,外界无法通过访问委托变量直接激发事件。下面的代码无法编译通过:Publisher p = new Publisher(); p.MyEvent(10);
            }
        }        
    }


参考资料:[大牛之路]C#高级知识点概要(1)-委托和事件

                      http://lib.csdn.net/article/dotnet/34658?knId=1198#focustext

===================================================================================


补充1:运用委托,对于只使用一次的方法,可直接用lambda表达式代替,不用额外创建一个方法

delegate int Calculator(int x);class Program {    static int Double(int x) { return x * 2; }    static void Main(string[] args) {        int[] values = { 1,2,3,4};        Utility.Calculate(values, Double);        foreach (int i in values)            Console.Write(i + " "); // 2 4 6 8        Console.ReadKey();    }}class Utility {    public static void Calculate(int[] values, Calculator c) {        for (int i = 0; i < values.Length; i++)            values[i] = c(values[i]);    }}

这个例子中的Utility是固定不变的,程序实现了整数的Double功能。我们可以把这个Double方法看作是一个插件,如果将来还要实现诸如求平方、求立方的计算,我们只需向程序中不断添加插件就可以了。

如果Double方法是临时的,只调用一次,若在整个程序中不会有第二次调用,那么我们可以在Main方法中更简洁更灵活的使用这种插件式编程,无需先定义方法,使用λ表达式即可,如:

...Utility.Calculate(values, x => x * 2);...

以后我们会经常写这样的代码。



原帖地址:http://www.cnblogs.com/willick/p/4172174.html

目前水平太渣,待心中有谱,再与大家评论交流。


0 0
原创粉丝点击