C#基础教程(四)接口实现事件

在写WPF教程的MVVM篇章时,会碰到接口INotifyPropertyChanged,里面只有 一个event PropertyChangedEventHandler PropertyChanged事件,因此引申出本章。

可以在接口中声明事件,然后在类中实现该事件的引用。在为方法订阅事件时,可以订阅接口声明的事件,也可以订阅类中的事件。我们看下面这个例子。

public class CustomEventArgs : EventArgs
{
    private double area;
    public double Area
    {
        get { return area; }
        set { area = value; }
    }
    public CustomEventArgs(double a)
    {
        area = a;
    }
}
public interface IDrawingObject
{
    event EventHandler<CustomEventArgs> ShapeChanged;//定义一个标准事件
}
public class Shape : IDrawingObject
{
    public event EventHandler<CustomEventArgs> ShapeChanged;
    public void RaiseEvent()//事件触发器
    {
        OnShapeChanged(new CustomEventArgs(10));//触发事件
    }
    protected virtual void OnShapeChanged(CustomEventArgs e)
    {
        if (ShapeChanged != null)
        {
                ShapeChanged(this, e);
        }
    }
}
class Program
{
    static private void HandlerShapeChanged(object sender,EventArgs e)
    {
        CustomEventArgs msg=e as CustomEventArgs;
        Console.WriteLine(msg.Area);
    }
    static void Main(string[] args)
    {
        Shape s = new Shape();
        IDrawingObject ido = s;
        //为HandlerShapeChanged方法订阅接口中声明的事件
        ido.ShapeChanged += HandlerShapeChanged;
        //为HandlerShapeChanged方法订阅实现接口的事件
        //s.ShapeChanged += HandlerShapeChanged;
        s.RaiseEvent();
        Console.Read();
    }
}

我们深挖函数源码会发现很多地方会用事件访问器,这里 不妨顺带研习一下。

事件访问器类似属性访问器,事件访问器被命名为add和remove,一般情况下不需提供自定义事件访问器,因为在编译时会自动添加事件访问器。

       1.add事件访问器:当客户端订阅该事件,调用该访问器。

       2.remove事件访问器:当客户端取消订阅事件,调用该访问器。

我们现在对上面例子进行改造,用add和remove访问器来删减事件。Events类来替换Shape类,并且注意入口函数里的注释。

public class Events : IDrawingObject
{
    public event EventHandler<CustomEventArgs> ShapeChanged;
    public event EventHandler<CustomEventArgs> IDrawingObj
    {
        add
        {            
            ShapeChanged += value;
        }
        remove
        {
            try
            {
                lock (ShapeChanged)//lock对象不能为null
                {
                    ShapeChanged -= value;
                }
            }
            catch { Console.WriteLine("对象为null"); }
        }
    }
    public void Raise(CustomEventArgs e)
    {
        try
        {
            ShapeChanged(this, e);
        }
        catch { }
    }
}
static void Main(string[] args)
{           
    Events s = new Events();
    s.IDrawingObj += HandlerShapeChanged;
    //s.IDrawingObj -= HandlerShapeChanged;//注掉为ShapeChanged为null
    //s.IDrawingObj -= HandlerShapeChanged;//注掉lock (ShapeChanged)报错,预先加try{} catch
    s.Raise(new CustomEventArgs(10));
    Console.Read();
}

总结

接口可以放事件,善于或用借口和事件,让代码更加美观。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章