熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

理解C#中的代理和事件(一)

2022-06-13   來源: .NET編程 

  突然寫這篇文章真的有點是在做作的感覺我想這並不是什麼難以理解的東西事實上很多人都寫過而且我保證至少不比我寫的差可是還是覺得有必要提出來因為要去正確的理解代理和事件是很有趣的也是很必要的那麼好吧下面我就來講講它們之間的關系當然還會有些例子

   

  首先我想說說有關事件事件顧名思義當然是windows程序收到的消息

   

  那麼我舉幾個有關事件的例子如鼠標移動按下之類的都是那麼代理呢?很多人都說它看上去就是想是一個受托管的函數指針我覺得這種說法很正確事實如此在MSDN上我們經常可以看到有關代理的多路廣播這個詞我覺得不錯可是不好理解但我會在下面詳細講解的

   

  代理:(有的書上也翻譯成指代或委托英文是這樣一來的Delegate)

   

  我想很多剛接觸C#的人都會對代理產生興趣的事實上也是如此不了解它你就沒辦法來做windows程序和傳統意義上的函數指針有所不同的是代理在C#中是一種類型這樣它看上去更安全也更符合OO精神代理實際上所做的工作就是通過引用把函數包裹起來並使函數有一個有效的返回值不知道我這樣說是否好理解那麼我舉個例子你去建造房子很顯然我是在說你所做的事情那麼建造房子就是代理它指代了你要做的事情可是它並沒有去做任何事情事實上是在建造房子這個工作裡你做了那麼結果是什麼?當然是建立一座房子是的建造房子就是代理而如何建造房子則是函數應該完成的工作而建造的是什麼樣的房子則是返回值還記得我曾經說過代理是一種類型嗎?呵呵我想你應該記得因為那是很新穎的至少當時我那麼認為好吧讓我們來看看名稱空間SystemDelagate看見了嗎?那就代理類

   

  舉個例子:

   

  public delegate void GetString()//我申明了一個代理

   

  現在我要用到它了如下;

   

  int i=;

  GetString gs=new GetString(iToString);//這裡我吧int的ToString方法填入了一個代理中看上去想構造函數這就是常在書上看到的名稱等效的而不是結構等效的我想看到這兒你還是不明白那麼我再來一個代理

   

  如下:

   

  float j=;

   

  GetString gs=new GetString(jToString);//瞧見了int的ToString方法和float的ToString方法的結構是不一樣的可是名稱和類型的返回值和參數都一樣現在我想你應該理解了吧

   

  可是我們經常會在MSDN中看到這樣的句子單路代理和多路廣播看上去有點不好理解

   

  事實上我開始看這樣的句子是有點頭痛的那麼我想例子是最好的解說方式

   

  Single Delegate:(單路代理)

   

  從字面上我們可以這樣來理解這個代理只是單單代理了一個函數的工作那麼好吧讓我們來看看它是如何工作的下面我就來定義一個這樣的代理:

   

  public delegate bool Myfun(string strint i)

   

  現在我再來寫一個方法如下:

   

  bool CompareStrToInt(string sint i)

  {

  if(sCompareTo(iToString())==)

  return true;

  else

  return false;

  }

   

  這個方法完成的工作很簡單對吧只是比較字符而已那麼和代理有什麼關系呢?還記得我說的話嗎?代理就是在把動詞名詞化代碼如下:

   

  Myfun mf=new  (CompareStrToInt);

   

  string s=;

  int i=;

  ConSoleWriteLine(Value=+mf(si));

   

  輸出結果:

   

  Value=true

   

  這就是單路代理它只代理一個好吧也許你想看看復雜的例子更有趣的在後面呢該是討論多路廣播的時候了

   

  多路廣播:

   

  一個代理同時代理幾個方法就是我們前面說到的那樣你去建造房子現在要不僅僅是建造住宅還的去建造花園等等其它建築物可是它們都是在建造房子傳遞的參數也相同返回值的類型也相同都是房屋那麼我們為什麼不找一個代理人來完成這樣的任務呢?把這些事物交由他一個人來完成不是可以節省我們很多的時間和金錢是的我們可以那樣做SystemMulticastDelegate 實際上 framework中你還可以找到這個類多路代理MSDN上翻譯成多路廣播事實上它還重載了操作符+=其實多路廣播和單路代理在使用方法上區別不大你可以看下面的例子

   

  using System;

   

  namespace Multi_castDelegate

  {

  /// <summary>

  /// Summary description for Class

  /// </summary>

  class MyClassDelegate

  {

  /// <summary>

  /// The main entry point for the application

  /// </summary>

   

  public delegate string IntDelegate(string s);

  }

  }

  using System;

   

  namespace Multi_castDelegate

  {

  /// <summary>

  /// Summary description for MyImplementingClass

  /// </summary>

  public class MyClass

  {

  public MyClass()

  {

   

  }

   

  public static string WriteString(string s)

  {

  ConsoleWriteLine(Writing string);

  return null;

  }

   

  public static string logString(string s)

  {

  ConsoleWriteLine(loging string);

  return null;

  }

   

  public static string TransmitString(string s)

  {

  ConsoleWriteLine(Transmitting string);

  return null;

   

  }

  }

  }

   

  The Main class:

  using System;

  using SystemThreading;

  namespace Multi_castDelegate

  {

  /// <summary>

  /// Summary description for Test

  /// </summary>

  public class Test

  {

  public static void Main()

  {

  MyClassDelegateStringDelegate

  WriterLoggerTransmitter;

   

  MyClassDelegateStringDelegate

  myDelegate;

   

  Writer=new

  MyClassDelegateStringDelegate(MyClassWriteString);

  /// calling Writer

  Writer(hello i am Writer just acting like Single cast);

  Logger=new MyClassDelegateStringDelegate(MyClasslogString);

  ///calling Logger

  Logger(hello i am Logger just acting like Singlecast);

  Transmitter=new MyClassDelegateStringDelegate(MyClassTransmitString);

  ///calling Transmitter

  Transmitter(hello i am Transmitter just acting like Singlecast);

  ///here mydelegate used the Combine method of SystemMulticastDelegate

  ///and the delegates combine

  myDelegate=(MyClassDelegateStringDelegate)SystemDelegateCombine(WriterLogger);

  myDelegate(used Combine);

  ///here Transmitter is also added using the overloaded form of Combine

  myDelegate+=Transmitter;

  myDelegate(Using Overloaded Form);

  ///now using the Remove method

  myDelegate=(MyClassDelegateStringDelegate)SystemDelegateRemove(myDelegateWriter);

  myDelegate(Without Writer);

  ///overloaded Remove

  myDelegate=Transmitter;

  myDelegate(Without Transmitter);

  SystemThreadingThreadSleep();

   

  }

  }

  }

   

  (上面的例子是在一個國外網站上找到的覺得不錯就直接套用了)

   

  上面的例子重點是看那兩個已經重載的操作符=+=通過上面的例子你可以清楚的看到多路廣播是如何一次代理多個方法的當然你也可以刪除掉那些你不想要的用=操作符就可以了(那麼我將在下一篇討論事件)


From:http://tw.wingwit.com/Article/program/net/201311/11741.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.