C#依頼、イベントとコールバック関数の詳細
7630 ワード
.Netプログラミングで最もよく使われる要素で、イベントは必ずその1つです.ASPにおいてもNETはWINFrom開発中、フォームロード(Load)、ペイント(Paint)、初期化(Init)など.「protected void Page_Load(object sender,EventArgs e)」というコードは、誰も知らない人はいないと信じています.注意すると、非常に多くのイベントメソッドが「object sender,EventArgs e」という2つのパラメータを持っていることがわかります.これは依頼とよく似ているのではないでしょうか.一、依頼(委任とも呼ばれる本もある)依頼とは何か.この名前の意味は私たちに想像の空間を与えて、あなたはプログラミングして、あなたは今ASPを書いています.NETのホームページ、JSはあなたがよく知らないので、あなたはあなたの同僚にJSの部分を完成するように依頼しました.これが依頼です.あなたができないことを他の人に任せます.どの人がやったのか、どうやって知ったのだろうか.もちろん名前を知っておく必要があります!名前のような異なる人を区別するためには、特徴を説明する必要があります.C#では、依頼の役割は、依頼は関数のポインタのように、プログラムの実行時に異なる関数を呼び出すために使用することができます.これは実はあなたが同僚にJSコードの完成を依頼したのと同じです.もし2人の同僚がこのことをすることができるならば、彼らはした結果があなたの需要を満たすことができる(インタフェースのように)限り、彼らのした過程は異なっていて、しかもした効果も異なっていますが、しかし、あなたの要求を達成することができます.1、簡単な依頼では、依頼にはどのような情報が必要ですか?まず、メソッド名と、パラメータリスト(メソッド署名)、および返されるタイプが格納されます.たとえば、delegate string/*戻りタイプ*/ProcessDelegte(int i);これが依頼の定義です.青い部分は依頼を宣言するキーワードで、赤い部分は返すタイプで、黒い部分は依頼のタイプ名で、1つのクラス名と差は多くありませんが、()の中はパラメータ部分です.この依頼を使って仕事をするには、1、戻りタイプと依頼の戻りタイプが一致し、ここでstringタイプである.2、パラメータは1つしかなく、intタイプです.OK、以上の2つの条件を満たして、すべて仕事ができます:)例えば:
2、汎用依頼汎用の依頼は、然パラメータのタイプが不確定であり、例えばコードが次のように書き換えられる.
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4
5 namespace TestApp
6 {
7 /// <summary>
8 ///
9 /// </summary>
10 /// <param name="s1"></param>
11 /// <param name="s2"></param>
12 /// <returns></returns>
13 public delegate string ProcessDelegate(string s1, string s2);
14
15 class Program
16 {
17 static void Main(string[] args)
18 {
19 /* */
20 ProcessDelegate pd = new ProcessDelegate(new Test().Process);
21 Console.WriteLine(pd("Text1", "Text2"));
22 }
23 }
24
25 public class Test
26 {
27 /// <summary>
28 ///
29 /// </summary>
30 /// <param name="s1"></param>
31 /// <param name="s2"></param>
32 /// <returns></returns>
33 public string Process(string s1,string s2)
34 {
35 return s1 + s2;
36 }
37 }
38 }
出力結果:Text 1 Tex 22、汎用依頼汎用の依頼は、然パラメータのタイプが不確定であり、例えばコードが次のように書き換えられる.
using System;
using System.Collections.Generic;
using System.Text;
namespace TestApp
{
/// <summary>
///
/// </summary>
/// <param name="s1"></param>
/// <param name="s2"></param>
/// <returns></returns>
public delegate string ProcessDelegate<T,S>(T s1, S s2);
class Program
{
static void Main(string[] args)
{
/* */
ProcessDelegate<string,int> pd = new ProcessDelegate<string,int>(new Test().Process);
Console.WriteLine(pd("Text1", 100));
}
}
public class Test
{
/// <summary>
///
/// </summary>
/// <param name="s1"></param>
/// <param name="s2"></param>
/// <returns></returns>
public string Process(string s1,int s2)
{
return s1 + s2;
}
}
}
出力の結果,Text 1100汎用型の詳細は本稿の紹介範囲に属さず,ここではこれ以上述べない.二、イベントある事件が発生した時、あるオブジェクトはイベントを通じて別のオブジェクトに通知することができる.例えば、フロントがフロントインタフェースを完了したら、フロントとあなたが開発したプログラムを統合できることを知らせます.これが事件です.事件はある時点で別のことをトリガーし、別のことをどうするか、彼は関心を持っていないことがわかります.事件について言えば、肝心なのはいつ、誰にやらせるかです.C#では、時間定義キーワードはeventです.例:event ProcessDelegate ProcessEvent;イベント全体の定義方法および実行手順:using System;
using System.Collections.Generic;
using System.Text;
namespace TestApp
{
/// <summary>
///
/// </summary>
/// <param name="s1"></param>
/// <param name="s2"></param>
/// <returns></returns>
public delegate void ProcessDelegate(object sender, EventArgs e);
class Program
{
static void Main(string[] args)
{
/* */
Test t = new Test();
/* , */
t.ProcessEvent += new ProcessDelegate(t_ProcessEvent);
/* Process */
Console.WriteLine(t.Process());
Console.Read();
}
static void t_ProcessEvent(object sender, EventArgs e)
{
Test t = (Test)sender;
t.Text1 = "Hello";
t.Text2 = "World";
}
}
public class Test
{
private string s1;
public string Text1
{
get { return s1; }
set { s1 = value; }
}
private string s2;
public string Text2
{
get { return s2; }
set { s2 = value; }
}
public event ProcessDelegate ProcessEvent;
void ProcessAction(object sender, EventArgs e)
{
if (ProcessEvent == null)
ProcessEvent += new ProcessDelegate(t_ProcessEvent);
ProcessEvent(sender, e);
}
// ,
void t_ProcessEvent(object sender, EventArgs e)
{
throw new Exception("The method or operation is not implemented.");
}
void OnProcess()
{
ProcessAction(this, EventArgs.Empty);
}
public string Process()
{
OnProcess();
return s1 + s2;
}
}
}
何を感じた?コード注入と差が少ないかどうかは,依頼インタフェース(依頼は確かにインタフェースに似ている)に任意に合致するコードでProcessプロセスに注入できることに相当する.彼が戻る前に彼に値をつけた.三、コールバック関数はこんなにたくさんの字を打って、疲れましたね.コールバック関数は,一つの方法を別の方法に伝達して実行することである.C#には非同期操作などのコールバック関数がたくさんあります.ここではまず例を挙げます.using System;
using System.Collections.Generic;
using System.Text;
namespace TestApp
{
/// <summary>
///
/// </summary>
/// <param name="s1"></param>
/// <param name="s2"></param>
/// <returns></returns>
public delegate string ProcessDelegate(string s1, string s2);
class Program
{
static void Main(string[] args)
{
/* */
Test t = new Test();
string r1 = t.Process("Text1", "Text2", new ProcessDelegate(t.Process1));
string r2 = t.Process("Text1", "Text2", new ProcessDelegate(t.Process2));
string r3 = t.Process("Text1", "Text2", new ProcessDelegate(t.Process3));
Console.WriteLine(r1);
Console.WriteLine(r2);
Console.WriteLine(r3);
}
}
public class Test
{
public string Process(string s1,string s2,ProcessDelegate process)
{
return process(s1, s2);
}
public string Process1(string s1, string s2)
{
return s1 + s2;
}
public string Process2(string s1, string s2)
{
return s1 + Environment.NewLine + s2;
}
public string Process3(string s1, string s2)
{
return s2 + s1;
}
}
}
出力結果:Text 1 Text 2 Text 1 Text 2 Text 2 Text 2 Text 1 Processメソッドはコールバック関数を呼び出し、もちろんここではコールバック関数のみが実行されます.この依頼に合致するいずれかの方法を伝えることができ,この部分のコードが可変であることを意味する.設計には可変部分コードを抽出する原則があり、この使い方は間違いなくその場合に使える.