如何在C#中的委託實現
先說下我為什麼會用委託。在最開始想用委託的時候,其實我是拒絕的。為什麼?因為結構看起來會有點亂啊,只是寫個方法名,然後在括號寫幾個引數,但是實現卻不在當前的物件中,給別人看的時候很不容易找誒。並且你一個委託擺在這,誰知道你的實現是幹嘛的,並且對於習慣了封裝的編寫方式之後,這個方式用的很不習慣。那麼問題來了,我怎麼會還要用呢。因為我要向介面寫一些顯示資料,但是那個控制元件物件在其它類中訪問不到啊。c#不像C++,定義一個全域性物件很容易,也不想安卓的介面編寫有個很好用的訊息機制可以重新整理介面。所以沒辦法我只能採用委託了,具體實現的方法只能放在介面物件。
委託的型別我接觸了兩種:
1、很常見的delegate;
2、也很常見action<T>,T表示一種資料型別,也就是說這種定義委託的方式,只能有一個引數。
定義好委託, 接下來就要定義事件了。如下所示:(比如這個委託在class showInfo這個物件中)
public delegate void showSomething(string message,int Type);
public event showSomething show;
這樣一個委託就定義好了。
這個時候就要有呼叫和實現了,實現簡單,比如在一個窗體的繼承類中定義如下:
class myFrom:Froms
{
showInfo myInfo;
myFrom()
{
myInfo.show += showSomething;
}
public void showSomething(string,int Type)
{
//do something;
}
}
這樣就把實現和事件繫結在一起了,不過在showInfo物件中對show進行呼叫時,最好先判斷一下if(show == null)只是為了規範。
你以為這樣就完了嗎??其實是沒有的。寫過安卓開發的人都知道,在重新整理介面是不能再子執行緒中實現的,最好的方式是通過訊息機制去實現。如果你不知道安卓的訊息機制,我只能說這不是重點,重點是C#介面的控制元件訪問也很坑爹。
如果你在上面的實現中直接訪問了C#的介面控制元件,這個時候很可能會報錯:執行緒間操作無效: 從不是建立控制元件的XX的執行緒訪問它。
坑吧,我被坑哭了。這錯誤不莫名其妙嘛?我在視窗類中呼叫的視窗中的控制元件,你卻告訴我的執行緒不對。仔細想想還真不對,這是C#為了保證執行緒訪問安全的一種保護機制,所以我才對委託很不爽啊。可是要解決這個問題,我不得不又用了一把心酸類----委託,是的又是委託。
網上提示了三種委託方式,第一種很簡單,就是把控制元件執行緒安全訪問的屬性設定成false就行了。我覺得這種方式太low,一點技術含量沒有,完全體現不了我的水平果斷pass了。
接下來的方法就是窗體的委託:Form.Invoke(Delegate method, params object[] args);第一個引數是委託的方法,第二個引數就是委託方法的引數了。
具體實現如下 :
public void ShowMessage(string message,int type)
{
this.Invoke(new Action<string>(delegate(string showmessage)
{
try
{
do something;
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}), message);
}
在上面的try中就可以正常的訪問框體的控制元件了,至此大功告成,不喜勿碰!