C#學習筆記(補充)——擴充套件方法、事件

andong777發表於2019-02-16

一、擴充套件方法

擴充套件方法使你能夠向現有型別“新增”方法,而無需建立新的派生型別、重新編譯或以其他方式修改原始型別。

注意事項:

  • 擴充套件方法需要是靜態方法。
  • 第一個引數指明作用的型別,並且用this關鍵字修飾。
  • 其他引數跟在第一個引數的後面。
  • 需要使用using指令將擴充套件方法所在的名稱空間匯入到原始碼中。
  • 該型別以例項方法的形式呼叫該方法。
  • 編譯器生成的中間語言 (IL) 會將程式碼轉換為對靜態方法的呼叫。
  • 擴充套件方法無法訪問它們所擴充套件的型別中的私有變數。

注意到C#中的StringBuilder類沒有實現Java中的Reverse()方法,可以通過擴充套件方法實現:

namespace ExtensionMethod
{
    public static class StringBuilderExtension
    {
        public static StringBuilder Reverse(this StringBuilder builder)
        {
            StringBuilder result = new StringBuilder();
            for(int i=builder.Length-1;i>=0;i--)
            {
                result.Append(builder[i]); 
            }
            return result;
        }
    }
}

新建一個測試類進行測試:

using ExtensionMethod;
static class TestStringBuilderExtension
{
    static void Main()
    {
        StringBuilder builder = new StringBuilder("ABC");
        StringBuilder newBuilder = builder.Reverse();
        Console.WriteLine(newBuilder);
        Console.Read();
    }
}

成功為StringBuilder新增了翻轉的方法。

事件

C#中使用委託來實現事件。使用了觀察者模式,即有一個事件的釋出者Publisher,和事件的訂閱者Subscriber。

委託需要有兩個引數,第一個引數為object型別,表示事件的傳送者,第二個引數為EventArgs型別或繼承自它。
但通常建議使用.Net Framework定義的事件模式,使用EventHandler類。EventHandler又分為使用泛型和不使用泛型兩種情況。

  1. 使用自定義的委託型別:

    public delegate void CustomEventHandler(object sender, CustomEventArgs a);
    
  2. 非泛型的EventHandler:

    public event EventHandler RaiseCustomEvent;
    
  3. 泛型的EventHandler:

    public event EventHandler<CustomEventArgs> RaiseCustomEvent;
    

處理事件的方法應該是宣告的委託的型別。

void HandleCustomEvent(object sender, CustomEventArgs a){ /* do something here */ }

訂閱事件使用+=,取消訂閱使用-=

publisher.RaiseCustomEvent += HandleCustomEvent;

以使用泛型的情況為例,假設事件發生呼叫OnRaiseCustomEvent方法。

class Publisher
    {
        public event EventHandler<CustomEventArgs> RaiseCustomEvent;
        public void DoSomething()
        {
            OnRaiseCustomEvent(new CustomEventArgs("Did something"));
        }
        protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
        {
            if (RaiseCustomEvent != null)
            {
                RaiseCustomEvent(this, e);
            }
        }
    }

訂閱者在其建構函式新增訂閱:

class Subscriber
{
    public Subscriber(Publisher pub)
    {
        pub.RaiseCustomEvent += HandleCustomEvent;
    }
    void HandleCustomEvent(object sender, CustomEventArgs e){ /* some implementation */ }
}

參考資料

[1] http://technet.microsoft.com/zh-cn/bb383977

[2] http://msdn.microsoft.com/zh-cn/library/8627sbea.aspx

[3] http://msdn.microsoft.com/zh-cn/library/ms366768.aspx

[4] http://msdn.microsoft.com/zh-cn/library/w369ty8x.aspx

[5] http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.aspx

相關文章