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

發表于:2007-05-25來源:作者:點擊數: 標簽:事件代理理解中的
解C#中的代理和事件(一) 突然寫這篇文章,真的有點,是在做作的感覺,我想這并不是什么,難以 理解的東西,事實上,很多人都寫過,而且,我保證至少不比我寫的差.可是 還是覺得有必要提出來.因為要去正確的理解代理和事件是很有趣的,也是 很必要的.那么好吧,下面我就

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

  突然寫這篇文章,真的有點,是在做作的感覺,我想這并不是什么,難以

理解的東西,事實上,很多人都寫過,而且,我保證至少不比我寫的差.可是

還是覺得有必要提出來.因為要去正確的理解代理和事件是很有趣的,也是

很必要的.那么好吧,下面我就來講講,它們之間的關系.當然還會有些例子.

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

那么我舉幾個有關事件的例子,如鼠標移動.按下.之類的都是.那么代理呢?

很多人都說它看上去,就是想是一個受托管的函數指針.我覺得這種說法很

正確,事實如此.在MSDN上,我們經??梢钥吹?有關代理的"多路廣播"這個詞

我覺得不錯,可是不好理解.但我會在下面詳細講解的.


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

我想很多剛接觸C#的人,都會對代理產生興趣的.事實上也是如此,不了解它,你就沒辦法

來做windows程序.和傳統意義上的函數指針有所不同的是,代理在C#中是一種類型,這樣

它看上去,更安全也,更符合OO精神.代理實際上所做的工作就是通過引用把函數包裹起來

并使函數有一個有效的返回值.不知道我這樣說是否好理解.那么我舉個例子,你去建造房子.

很顯然,我是在說你所做的事情.那么建造房子就是代理,它指代了,你要做的事情,可是它并

沒有去做任何事情,事實上是,在建造房子這個工作里,你做了,那么結果是什么?當然是建立

一座房子.是的,建造房子就是代理,而如何建造房子則是函數應該完成的工作.而建造的是什么樣

的房子,則是返回值.還記得,我曾經說過,代理是一種類型嗎?呵呵..我想你應該記得,因為,

那是很新穎的,至少當時我那么認為.好吧,讓我們來看看名稱空間System.Delagate,看見了嗎?那

就代理類.

舉個例子:
public delegate void GetString()//我申明了一個代理

現在我要用到它了如下;
int i=100;
GetString gs=new GetString(i.ToString);//這里我吧int的ToString方法

填入了一個代理中.看上去想構造函數.這就是常在書上看到的"名稱等效的,而

不是結構等效的",我想看到這兒你還是不明白.那么,我再來一個代理

如下:

float j=0.0001;

GetString gs=new GetString(j.ToString);//瞧見了,int的ToString方法

和float的ToString方法的結構是不一樣的,可是名稱和類型的返回值和

參數都一樣.現在,我想,你應該理解了吧.


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

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

Single Delegate:(單路代理)

從字面上,我們可以這樣來理解,這個代理只是單單代理了一個函數的工作.那么好吧,讓

我們來看看它是如何工作的.下面我就來定義一個這樣的代理:

public delegate bool Myfun(string str,int i)


現在我再來寫一個方法如下:
 
bool CompareStrToInt(string s,int i)
{
   if(s.CompareTo(i.ToString())==0)
        return true;
    else
         return false;
}

這個方法完成的工作很簡單對吧,只是比較字符而已.那么和代理有什么關系呢?還記得

我說的話嗎?代理就是在把動詞名詞化.代碼如下:

Myfun mf=new  (CompareStrToInt);

string s="10000";
int i=10000;
ConSole.WriteLine("Value="+mf(s,i));

輸出結果:

Value=true

這就是單路代理.它只代理一個.好吧,也許你想看看復雜的例子,更有趣的在后面呢,

該是討論多路廣播的時候了.


多路廣播:


一個代理同時代理幾個方法.就是我們前面說到的那樣,你去建造房子,現在要不僅僅是

建造住宅,還的去建造花園等等其它建筑物.可是它們都是在建造房子,傳遞的參數也相同

返回值的類型也相同都是房屋.那么我們為什么不找一個代理人來完成這樣的任務呢?把

這些事物交由他一個人來完成不是可以節省我們很多的時間和金錢.是的我們可以那樣做

System.MulticastDelegate 實際上在.net framework中你還可以找到這個類,多路代理

MSDN上翻譯成多路廣播.事實上它還重載了操作符+=.其實多路廣播和單路代理在使用方法

上區別不大.你可以看下面的例子.


using System;

namespace Multi_castDelegate
{
  /// <summary>
  /// Summary description for Class1.
  /// </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)
    {
      Console.WriteLine("Writing string");
      return "null";
    }

    public static string logString(string s)
    {
      Console.WriteLine("loging string"); 
      return "null";
    }

    public static string TransmitString(string s)
    {
      Console.WriteLine("Transmitting string"); 
      return "null";
      
    }
  }
}

The Main class:
using System;
using System.Threading;
namespace Multi_castDelegate
{
  /// <summary>
  /// Summary description for Test.
  /// </summary>
  public class Test
  {
    public static void Main()
    {
      MyClassDelegate.StringDelegate
        Writer,Logger,Transmitter;

      MyClassDelegate.StringDelegate
        myDelegate;

      Writer=new
                   MyClassDelegate.StringDelegate(MyClass.WriteString);
      /// calling Writer
      Writer("hello i am Writer just acting like Single cast");
      Logger=new MyClassDelegate.StringDelegate(MyClass.logString);
      ///calling Logger
      Logger("hello i am Logger just acting like Single-cast");
      Transmitter=new MyClassDelegate.StringDelegate(MyClass.TransmitString);
      ///calling Transmitter
            Transmitter("hello i am Transmitter just acting like Single-cast"); 
      ///here mydelegate used the Combine method of System.MulticastDelegate
      ///and the delegates combine  
      myDelegate=(MyClassDelegate.StringDelegate)System.Delegate.Combine(Writer,Logger); 
            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=(MyClassDelegate.StringDelegate)System.Delegate.Remove(myDelegate,Writer);
            myDelegate("Without Writer");    
      ///overloaded Remove
      myDelegate-=Transmitter;
      myDelegate("Without Transmitter");
        System.Threading.Thread.Sleep(2300);  
           
    }
  }
}

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

上面的例子重點是看那兩個已經重載的操作符."-="和"+=".通過上面的例子,你可以清楚的

看到多路廣播是如何一次代理多個方法的.當然你也可以刪除掉那些你不想要的用"-="操作

符就可以了.(那么我將在下一篇討論事件)

原文轉自:http://www.anti-gravitydesign.com

評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97