日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > C# >内容正文

C#

委托C# 生活 实例

發(fā)布時(shí)間:2025/3/19 C# 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 委托C# 生活 实例 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

現(xiàn)實(shí)中的例子:
比如說(shuō)一個(gè)公司(場(chǎng)景),你是老板,手下有兩個(gè)員工,小張和小王。
你命令小王,如果小張玩游戲,則小王扣去小張500元錢(qián)。
這就是現(xiàn)實(shí)中的委托。
實(shí)際上,在寫(xiě)程序中,程序員就是老板,小張和小王就是兩個(gè)對(duì)象。小張玩游戲是一個(gè)方法,小張還有一個(gè)游戲事件,他玩游戲激發(fā)這個(gè)事件。而小王就是事件處理對(duì)象,他負(fù)責(zé)把小張的錢(qián)扣除500。
所以,委托有如下幾個(gè)要素:
1 激發(fā)事件的對(duì)象--就是小張
2 處理對(duì)象事件的對(duì)象--就是小王
3 定義委托,就是你讓小王監(jiān)視小張。
如果這三個(gè)要素都滿(mǎn)足的話(huà),則你就寫(xiě)出了一個(gè)完整事件的處理。
下面有個(gè)例子:在vs.net2003 C#控制臺(tái)應(yīng)用程序編輯運(yùn)行成功:
using System;
namespace CSharpConsole
{
public class 場(chǎng)景
{
[STAThread]
public static void Main(string[] args)
{
Console.WriteLine("場(chǎng)景開(kāi)始了....");
// 生成小王
小王 w = new 小王();
// 生成小賬
小張 z = new 小張();
// 指定監(jiān)視
z.PlayGame += new PlayGameHandler(w.扣錢(qián));
// 開(kāi)始玩游戲
z.玩游戲();
console.writeline("場(chǎng)景結(jié)束...");
Console.ReadLine();
}
}

// 負(fù)責(zé)扣錢(qián)的人
public class 小王
{
public 小王()
{
Console.WriteLine("生成小王...");
}
public void 扣錢(qián)(object sender,EventArgs e)
{
Console.WriteLine("小王:好小子,上班時(shí)間膽敢玩游戲...");
Console.WriteLine("小王:看看你小子有多少錢(qián)...");
小張 f = (小張)sender;
Console.WriteLine("小張的錢(qián): " + f.錢(qián).ToString());
Console.WriteLine("開(kāi)始扣錢(qián)......");
System.Threading.Thread.Sleep(500);
f.錢(qián) = f.錢(qián) - 500;
Console.WriteLine("扣完了....現(xiàn)在小張還剩下:" + f.錢(qián).ToString());
}
}
// 如果玩游戲,則引發(fā)事件
public class 小張
{
// 先定義一個(gè)事件,這個(gè)事件表示“小張”在玩游戲。
public event PlayGameHandler PlayGame;
// 保存小張錢(qián)的變量
private int m_Money;
public 小張()
{
Console.WriteLine("生成小張....");
m_Money = 10000; // 構(gòu)造函數(shù),初始化小張的錢(qián)。
}
public int 錢(qián) // 此屬性可以操作小張的錢(qián)。
{
get
{
return m_Money;
}
set
{
m_Money = value;
}
}
public void 玩游戲()
{
Console.WriteLine("小張開(kāi)始玩游戲了.....");
Console.WriteLine("小張:CS好玩,哈哈哈! 我玩.....");
System.Threading.Thread.Sleep(500);
System.EventArgs e = new EventArgs();
//OnPlayGame(e);
if(PlayGame != null)
{
PlayGame(this,e);
}
}
protected virtual void OnPlayGame(EventArgs e)
{
if(PlayGame != null)
{
PlayGame(this,e);
}
}
}
// 定義委托處理程序
public delegate void PlayGameHandler(object sender,System.EventArgs e);
}

=========================================================
剛開(kāi)始在理解委托和事件時(shí)常常被msdn搞糊涂,為了快速應(yīng)用.net的委托和事件模型編程,可以先看看如下的代碼
using System;
namespace delegeteTest
{
class delegeteClass
{
public delegate void fHandler(int a); //關(guān)鍵-此行可以看成類(lèi)的聲明
public fHandler f0;
public void d(int a,int b )
{
int c=a+b;
f0(c);
}
}
class test
{
public void output(int mun)
{
System.Console .WriteLine ("{0}",mun);
}
[stathread]
static void Main(string[] args)
{
test t=new test ();
delegeteClass dc=new delegeteClass ();
dc.f0 =new delegeteTest.delegeteClass.fHandler (t.output);//實(shí)例的初始化
dc.d(2,3);
}
}
}
解釋一下"關(guān)鍵": 實(shí)際上 public delegate void fHandler(int a);可以看成如下:
class fHandler
{.....}
類(lèi)內(nèi)部由編譯器自動(dòng)完成,是一個(gè)sealed類(lèi)通過(guò)反匯編可以看到,是一個(gè)類(lèi)的聲明,它檢查加入自己的函數(shù)的信息,如,返回值和參數(shù)類(lèi)型
現(xiàn)在熟悉vc++的人可能感覺(jué)到public delegate void fHandler(int a);這句就象一個(gè)宏
現(xiàn)在好了既然是個(gè)類(lèi)的定義,那么也可以直接拿到命名空間下了
using System;
namespace delegeteTest
{
public delegate void fHandler(int a);//fHandler現(xiàn)在上升到了類(lèi)的層次
class delegeteClass
{
public fHandler f0;//聲明了委托fHandler的實(shí)例f0;
public fHandler f1;//也可以再聲明一個(gè)fHandler類(lèi)的實(shí)例f1;
public void d(int a,int b )
{
int c=a+b;
f0(c);
}
}
class test
{
public void output(int mun)
{
System.Console .WriteLine ("{0}",mun);
}
[stathread]
static void Main(string[] args)
{
test t=new test ();
delegeteClass dc=new delegeteClass ();
dc.f0 =new delegeteTest.fHandler (t.output);//此行做相應(yīng)的修改
dc.d(2,3);
}
}
}
有以上可知public delegate void fHandler(int a)這行代碼只能放在能夠聲明類(lèi)的地方,自然fHandler.后面的函數(shù)都是靜態(tài)方法了,如fHandler.Equals (...);
那么fhandler到底聲明了什么? 實(shí)際上是聲明了函數(shù)的類(lèi)型,既函數(shù)的有關(guān)信息(如返回值,參數(shù)類(lèi)型)。說(shuō)到委托還是要說(shuō)一下委托類(lèi)型的實(shí)例。在msdn中的很多地方,(委托)這個(gè)詞指的是委托類(lèi)型的實(shí)例,它擁有了一個(gè)列表,列表的每一項(xiàng)包含了函數(shù)信息和函數(shù)所在的對(duì)象的引用。
在聲明fhandler類(lèi)的實(shí)例f0的時(shí)候,f0還不能用,是空的,所以f0需要初始化 dc.f0 =new delegeteTest.fHandler (t.output); 初始化的參數(shù)包含了兩個(gè)信息 t--對(duì)象的引用,output--函數(shù)信息,如果把初始化的這句注釋掉,你運(yùn)行一下看有什么信息----“未將對(duì)象引用設(shè)置到對(duì)象的實(shí)例”。另外output函數(shù)的參數(shù)和返回值需要和fHandler的類(lèi)聲明一致,這是由編譯器在編譯時(shí)檢查的。
經(jīng)過(guò)初始化之后 現(xiàn)在實(shí)例中有了一項(xiàng)數(shù)據(jù)(實(shí)際上大多數(shù)只有一項(xiàng),這樣效率比較高,也就是single cast的,此時(shí)實(shí)例是Delegate類(lèi)型的(注意是大寫(xiě)的D))。
現(xiàn)在說(shuō)一下委托的多播(multi cast),實(shí)際上委托的多播就是把列表里的每一項(xiàng)函數(shù)調(diào)用一次),但是多播的效率不是很高的所以委托的大部分實(shí)例都是單播(single cast),另外可能委托的實(shí)例會(huì)根據(jù)列表內(nèi)函數(shù)的個(gè)數(shù)來(lái)運(yùn)行不同的機(jī)制(這里我們就沒(méi)必要研究它了)。看下面的代碼:
namespace delegeteTest
{
public delegate void fHandler(int a);
class delegeteClass
{
public fHandler f0;
public fHandler f1;
public void d(int a,int b )
{
int c=a+b;
f1(c); //合并指針列表的多播委托
}
}
class test
{
public void output(int mun)
{
System.Console .WriteLine (" 函數(shù)1顯示{0}",mun);
}
public void output1(int mun)
{
System.Console .WriteLine (" 函數(shù)2顯示{0}",mun);
}
[stathread]
static void Main(string[] args)
{
test t=new test ();
delegeteClass dc=new delegeteClass ();
dc.f0 =new delegeteTest.fHandler (t.output);
dc.f1 =new fHandler (t.output1 );
system.console .WriteLine ("第一次觸發(fā)");
dc.d (2,3);//第一次觸發(fā)
dc.f1 =(fHandler)Delegate.Combine (dc.f0 ,dc.f1 );//合并生成新的]函數(shù)列表
dc.f1 =(fHandler)MulticastDelegate.Combine (dc.f1 ,dc.f0 );//同上
System.Console .WriteLine ("第二次觸發(fā)");
dc.d(2,3);//第二次觸發(fā)
}
}
}
實(shí)際上dc.f1 =(fHandler)MulticastDelegate.Combine (dc.f1 ,dc.f0 );和dc.f1 =(fHandler)Delegate.Combine (dc.f1 ,dc.f0 );效果是一樣的;由上面的例子可知我們完全可以由delegate 來(lái)構(gòu)造我們自己的事件。微軟為了方便大家進(jìn)行編程,為我們提供了event。
using System;
namespace delegeteTest
{
public delegate void fHandler(int a);
class delegeteClass
{
public fHandler f0;
public fHandler f1;
public event fHandler f3; //關(guān)鍵--實(shí)際上此行也可以看成一個(gè)宏
public void d(int a,int b )
{
int c=a+b;
f3(c); // 改由event進(jìn)行
}
}
class test
{
public void output(int mun)
{
System.Console .WriteLine (" 第1顯示{0}",mun);
}
public void output1(int mun)
{
System.Console .WriteLine (" 第2顯示{0}",mun);
}
[stathread]
static void Main(string[] args)
{
test t=new test ();
delegeteClass dc=new delegeteClass ();
dc.f0 =new delegeteTest.fHandler (t.output);
dc.f1 =new fHandler (t.output1 );
dc.f3 +=new fHandler(t.output); //f3是event
System.Console .WriteLine ("第一次觸發(fā)");
dc.d (2,3);//第一次觸發(fā)
system.console .WriteLine ("第二次觸發(fā)");
dc.f3 +=(fHandler)Delegate.Combine (dc.f0 ,dc.f1 );//添加列表到f3
dc.d(2,3);//第二次觸發(fā)
}
}
}
通過(guò)ildasm反匯編可以看到public event fHandler f3宏聲明了兩個(gè)成員
.field private class delegeteTest.fHandler f3和對(duì)f3的一個(gè)包裝:
.event delegeteTest.fHandler f3
{
.addon instance void delegeteTest.delegeteClass::add_f3(class delegeteTest.fHandler)
.removeon instance void delegeteTest.delegeteClass::remove_f3(class delegeteTest.fHandler)
},
所以上面部分代碼可以替換成如下:
private fHandler _f3;//由于不能與屬性名相同,所以用_f3,是私有
public event fHandler f3
{
add
{
this._f3 += value;
}
remove
{
this._f3 -= value;
}
}
event 關(guān)鍵字方便了大家的習(xí)慣,同時(shí)它(由event定義的事件)在類(lèi)的外部使用時(shí)隱藏了它的成員函數(shù)(這一點(diǎn)非常重要,幾乎就是使用event關(guān)鍵字的原因),并且只能用“+=”和“-=”來(lái)操作,除此之外和直接聲明public fHandler f3沒(méi)有區(qū)別。它可以和上面的f0,f1一樣允許有各種參數(shù)和返回值。是在委托基礎(chǔ)上的。實(shí)際上我們都能用delegate 來(lái)構(gòu)造我們想要的事件,這就是delegate 在.net里的地位很高的原因。
下面探討一般控件的事件模型
先談一下控件里的"on事件名"這個(gè)函數(shù) 如:OnTextChange(EventArgs e),類(lèi)似的有很多,實(shí)際上這是一種編程方面的習(xí)慣,他代表的是引發(fā)這個(gè)TextChanged事件(注意不是代表TextChanged(e)的函數(shù)),具體的說(shuō)就是在Text變量已經(jīng)被賦值后執(zhí)行的一個(gè)函數(shù)OnTextChanged(),OnTextChanged里面包含了類(lèi)似TextChanged(e)這樣的引發(fā)事件的代碼。如果你重寫(xiě)了OnTextChanged(),而沒(méi)有在(重寫(xiě)的函數(shù))里添加base.OnTextChanged(e);那么你在外部添加的TextChanged事件的處理程序,永遠(yuǎn)也不會(huì)觸發(fā)到,也就是TextChanged事件失效了。
下面寫(xiě)了一個(gè)重寫(xiě)ontextchanged()的例子,是關(guān)于只能輸入數(shù)字的textbox, 里面有輸入整數(shù)部分的數(shù)量限制屬性 MaxOfInt 和小數(shù)限制屬性MaxOfLittle,還有decimal 類(lèi)型的值 ValueDecimal屬性,還有一個(gè)DecmalValueChanged事件,由于重寫(xiě)了OnTextChanged事件而沒(méi)有在里面寫(xiě)base.TextChanged (e);所以你們?nèi)绻偈褂肨extChanged事件就一點(diǎn)效果都沒(méi)有了。
下面的控件不怕粘貼,不怕漢字
using System;
using System.ComponentModel;
using System.ComponentModel .Design ;
namespace contr
{
/// <summary>
///
/// </summary>
public class TextBoxNum : System.Windows.Forms.TextBox
{
public delegate void ValueChangedHandler(object o,decimal DecValue);
private ValueChangedHandler ValueChanged;//聲明了一個(gè)實(shí)例
public int MaxInt=8;
public int MaxLittle=2;
public decimal DecimalValue=0;
public TextBoxNum()
{
//
// TODO: 在此處添加構(gòu)造函數(shù)邏輯
//
}
private void InitializeComponent()
{
}
protected override void OnTextChanged(EventArgs e)
{
if(this.Text .Length !=0&&(this.Text[0])=='.')
{
this.Text ="0.";
this.SelectionStart=(this.Text .Length );
return;
}
string s=this.Text.Trim ();
if(this.MaxLittle ==0)
{
if(s.IndexOf ('.')>0||this.Text .Length >this.MaxInt )
{
this.Text =this.ValueDecimal .ToString ();
this.SelectionStart=(this.Text .Length );
return;
}
}
if(s ==""){return;}
int j=s .IndexOf ('.');
if((j<0&&s.Length >this.MaxInt ))
{
this.text =this.ValueDecimal .ToString ();
this.SelectionStart=(this.Text .Length );
return;
}
if(j>-1&&(s.Length -j-1)>this.MaxLittle)
{
this.Text =this.ValueDecimal .ToString ();
this.SelectionStart=(this.Text .Length );
return;
}
int a=0;
char[] temp=s.ToCharArray () ;
for(int i=0;i<s.Length ;i++)
{
if(Char.IsDigit(temp))
{
continue;
}
else if(temp=='.')
{
a++;
if(a>1)
{
this.Text =this.ValueDecimal .ToString ();
this.SelectionStart=(this.Text .Length );
return;
}
continue;
}
this.Text =this.ValueDecimal .ToString ();
this.SelectionStart=(this.Text .Length );
return;
}
this.ValueDecimal =decimal.Parse (this.Text);
base.TextChanged (e);
}
public event ValueChangedHandler DecmalValueChanged
{
add
{
this.ValueChanged += value;
}
remove
{
this.ValueChanged -= value;
}
}
public decimal ValueDecimal
{
get
{
return this.DecimalValue ;
}
set
{
this.DecimalValue =value;
if(ValueChanged!=null)
{
ValueChanged(this,this.DecimalValue );
}
}
}
[Browsable(true),DefaultValue(8)]
public int MaxOfInt
{
get
{
return this.MaxInt ;
}
set
{
if(value<=29)
{
this.MaxInt =value;
this.MaxLength =this.MaxLittle +value +1;
}
else
{
this.MaxInt =29;
this.MaxLength =this.MaxLittle +29 +1;
}
}
}
[Browsable(true),DefaultValue(2)]
public int MaxOfLittle
{
get
{
return this.MaxLittle ;
}
set
{
if(value<=29)
{
this.MaxLittle =value;
this.MaxLength =value +this.MaxInt +1;
}
else
{
this.MaxLittle =29;
this.MaxLength =29 +this.MaxInt +1;
}
}
}
}
}

總結(jié)

以上是生活随笔為你收集整理的委托C# 生活 实例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。