您的位置:首页 > 编程语言 > C#

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

2017-04-12 23:28 323 查看
事件的标准用法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));
            }
        }
    }

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

[b]事件的标准用法2
[/b]

    class Program

    {

        static void Main(string[] args)

        {

            Apple ap1 = new Apple(){

               Preice = 5288

            };

            //注册事件

            ap1.myEvent += PriceChanged;

            //调整价格,触发事件

            ap1.Preice = 3999;

            Console.ReadKey();

        }

        


        [b]//事件响应程序

        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)

        {[/b]

            [b]//如果调用列表不为空,则触发

            if (myEvent != null)

            {

                myEvent(this, e);[/b]

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

            }

        }        

    }

参考资料:[大牛之路]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

目前水平太渣,待心中有谱,再与大家评论交流。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: