[リーディングノート] C#スタディノート2:デリゲートとイベントの使用法と違い。


[リーディングノート] C#スタディノート2:デリゲートとイベントの使用法と違い。


序文: 

C#デリゲートとは                                                                                                                                                                                              

c#の委任は、関数のラッパーとして理解できます。これにより、C#の関数をパラメーターとして渡すことができます。これは、C ++の関数ポインターと同等です。C++は、関数ポインターを使用して関数のエントリアドレスを取得し、これを介して機能の動作を実現するためのポインタ。

デリゲートの定義は、デリゲートキーワードが定義の前に追加されることを除いて、メソッドの定義に似ています。

 

テキスト:


デリゲートは、上位レベルのポインタと見なすことができ、アドレスを別の関数に渡すだけでなく、パラメータや戻り値などの複数の情報を渡すこともできます。
システムは、委任されたオブジェクトの同期および非同期の呼び出しメソッドも自動的に生成します。開発者は、BeginInvokeメソッドとEndInvokeメソッドを使用して、スレッドを破棄し、マルチスレッド呼び出しを直接使用できます。

 

1.
IL分析の委任は、DelegateがSystem.MulticastDelegateクラスを継承し、BeginInvoke、EndInvoke、およびInvokeの3つの一般的なメソッドを自動的に生成することを示しています。

Invokeメソッドは、デリゲートオブジェクトの対応するメソッドを同期的に呼び出すために使用され、BeginInvokeおよびEndInvokeは、対応するメソッドを非同期的に呼び出すために使用されます。

1.1単純な委任
委任オブジェクトを確立する場合、委任のパラメータータイプは委任メソッドに対応している必要があります。メソッド名example.Methodがデリゲートオブジェクトのコンストラクターに入力されている限り、デリゲートは単純です。

次に、このメソッドをバインドします。
myDelegate.Invoke(string message)を使用すると、デリゲートメソッドを明示的に呼び出すことができます。
ただし、実際の操作では、Invokeメソッドを使用する必要はなく、myDelegate(string message)を直接使用してdelegateメソッドを呼び出すだけです。

コードをコピーする

 1クラスプログラム2 {3 void MyDelegate(string message); 4 5 publicclass例6 {7 public void Method(string message)8 {9 MessageBox.Show(message); 10} 11} 12 13 static void Main(string [] args)14 {15例example = new Example() ; 16 MyDelegate myDelegate = new MyDelegate(example.Method); 17 myDelegate( "Hello World"); 18 Console.ReadKey(); 19} 20}

コードをコピーする

 

1.2戻り値のある委員会

デリゲートオブジェクトを作成する場合、デリゲートの戻り値はデリゲートメソッドに対応している必要があります。以下の例を使用すると、メソッドは「HelloLeslie」を返します。

コードをコピーする

 1 class Program 2 { 3     delegate string MyDelegate(string message); 4  5     public class Example 6     { 7         public string Method(string name) 8         { 9             return "Hello " + name;10         }11     }12 13     static void Main(string[] args)14     {15         Example example=new Example();16         //绑定委托方法17         MyDelegate myDelegate=new MyDelegate(example.Method);18         //调用委托,获取返回值19         string message = myDelegate("Leslie");20         Console.WriteLine(message);21         Console.ReadKey();22     }23 }

コードをコピーする

 

1.3 多路广播委托
在上面提过,委托类继承于MulticastDelegate,这使委托对象支持多路广播,即委托对象可以绑定多个方法。
当输入参数后,每个方法会按顺序进行迭代处理,并返回最后一个方法的计算结果。
下面的例子中,Price 类中有两个计算方法,Ordinary 按普通的9.5折计算,Favourable 按优惠价 8.5 折计算。
委托同时绑定了这两个方法,在输入参数100以后,Ordinary、Favourable这两个方法将按顺序迭代执行下去,最后返回 Favourable 方法的

计算结果 85。

コードをコピーする

 1 delegate double MyDelegate(double message); 2 public class Price 3 { 4     public double Ordinary(double price) 5     { 6         double price1 = 0.95 * price; 7         Console.WriteLine("Ordinary Price : "+price1); 8         return price1; 9     }10 11     public double Favourable(double price)12     {13         double price1 = 0.85 * price;14         Console.WriteLine("Favourable Price : " + price1);15         return price1;16     }17 18     static void Main(string[] args)19     {20         Price price = new Price();21         //绑定Ordinary方法22         MyDelegate myDelegate = new MyDelegate(price.Ordinary);23         //绑定Favourable方法24         myDelegate += new MyDelegate(price.Favourable);25         //调用委托26         Console.WriteLine("Current Price : " + myDelegate(100));27         Console.ReadKey();28     }29 }

コードをコピーする

 

1.4 Observer模式中的事件与委托 

コードをコピーする

 1 class Program 2 { 3     public delegate void ObserverDelegate(); 4      5     static void Main(string[] args) 6     { 7         // 具体主题角色通常用具体自来来实现 8         ConcreteSubject subject = new ConcreteSubject(); 9 10         //传入的只是观察者的通过方法。11         subject.Attach(new ConcreteObserver(subject, "Observer A").Update);12         subject.Attach(new ConcreteObserver(subject, "Observer B").Update);13         subject.Attach(new ConcreteObserver(subject, "Observer C").Update);14 15         subject.SubjectState = "Ready";16         subject.Notify();17 18         Console.Read();19     }20 21 22     //抽象主体类23     public abstract class Subject24     {25         public ObserverDelegate observerDelegate;26 27         //增加观察者28         public void Attach(ObserverDelegate observer)29         {30             observerDelegate += observer;31         }32 33         //移除观察者34         public void Remove(ObserverDelegate observer)35         {36             observerDelegate -= observer;37         }38 39         //像观察者发通知40         public void Notify()41         { 
42             if (observerDelegate != null)43             {44                 observerDelegate();45             }46         }47     }48 49     //具体主题类50     public class ConcreteSubject : Subject51     {52         public string SubjectState { get; set; }53     }54 55     //具体观察者56     public class ConcreteObserver57     {58         private string observerState;59         private string name;60         private ConcreteSubject subject;61 62         public ConcreteObserver(ConcreteSubject subject, string name)63         {64             this.subject = subject;65             this.name = name;66         }67 68         //实现抽象观察者中的更新操作69         public void Update()70         {71             observerState = subject.SubjectState;72             Console.WriteLine("The observer's state of {0} is {1}", name, observerState);73         }74     }75 }

コードをコピーする

 

第二に、イベント


(1)イベント中の代表団のカプセル化は、特別な代表団として理解することができます。
(2)イベントでは、実際には2つのメソッド(つまり、add_event()とremove_event())とプライベートデリゲート変数があります。これら2つのメソッドは、プライベートデリゲート変数を入力するために使用されます。

行のマージと削除。イベントの+ =が呼び出されると、実際には呼び出されたイベントのadd_event()メソッドであり、同じ-=がremove_event()メソッドを呼び出します
(3)イベントは、オブジェクトの外部からのみ新しい応答メソッドを追加できます。また、既知の応答方法を削除しますが、イベントをアクティブにトリガーしたり、他の登録済み応答方法やその他の情報を取得したりすることはできません。使用する場合

パブリックデリゲートはこれらの制限を行うことができません。つまり、イベントによってデリゲートが制限され、デリゲートの使用がより便利になります。
イベントは委員会のキャストであると言う人もいますが、それはおそらく同じです。

ここではイベントについての説明はあまりありません。イベントについての良いブログ投稿を見ました。それを読むことをお勧めします:http://www.cnblogs.com/landeanfen/p/4721525.html

PS:このブログはあなた自身の学習の成果を記録するためのものです。言われているように、良い記憶は悪いペンほど良くはありません。私はそれに固執できることを願っています。 

カテゴリ:  C#ベーシックシリーズ、 読書ノート

良い記事は 私の お気に入りの記事に注意を払う必要があります  

花はロマンチックだと考えられていますか


おすすめ

転載: blog.51cto.com/7592962/2543851
おすすめ