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();
}

總結

接口可以放事件,善於或用藉口和事件,讓代碼更加美觀。

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