一、为什么使用委托【引用CSDN】
(1)在写类的时候,根本就不能确定要调用哪个对象的方法:例如,你把自己的一个对象上的方法挂在微软的textbox 的一个事件上。微软在写textbox时根本就不可能知道这个事件发生时,需要调用哪个对象的哪个方法,只有你自己去指定说需要调什么方法,并且以委托的方式挂在相应的事件上。
微软在写textbox的事件时,唯一能确定的是这个事件的格式,或者说这个事件需要调用的方法的格式,
类似于 button1_click(object sender, EnentArgs e) 等等。 只要是按照这个类型写的方法,都能被挂在这个事件上,并且在事件发生时,方法会被调用。这只是基于消息驱动的实现方式之一。
(2)想象一下如果把你“用嘴吃东西的过程”封装成一个类吧:
其中对于吃这个动作是这么定义的:
public void 吃(食物)
{
把食物塞你嘴里(); // step 1
嘴开始有所动作(食物); // step 2
咽下去(是否可以咽下去); // step 3
}
注意步骤二,不同的食物你的嘴会采用不同的方式处理。
当食物==水,不会咀嚼直接咽
当食物==肉包子,当然要嚼嚼再咽
当食物==口香糖,只嚼不咽
当食物==鱼,你还要仔细的吐出鱼刺......
显然你不可能在你的类里预见到所有情形,这种情况下就可以把“嘴开始有所动作”考虑定义成委托,让客户端调用时给出具体实现,至于在类里,占个位而已。
二、实现委托的步骤
1.定义委托
2.定义委托实例
3.将方法登记到委托实例中
4.如果委托有登记事件,则执行实例
举两个个简单的例子:
//无参数的情况
public class Test { private delegate void CatShoutHandle(); private event CatShoutHandle CatShout; public void TestDelegate() { CatShout += new CatShoutHandle(c_CatShout); if (CatShout != null) { CatShout(); } } void c_CatShout() { Console.WriteLine("This is my Test Delagate!"); } static void Main() { Test c = new Test(); c.TestDelegate(); return; } }
有参数情况
//有参数情况
public class MyParameter:EventArgs { private string name; public MyParameter(string _name) { this.name = _name; } public string Name { get { return name; } set { name = value; } } } public class Test { private delegate void CatShoutHandle(object sender,MyParameter para); private event CatShoutHandle CatShout; public void TestDelegate() { CatShout += new CatShoutHandle(Test_CatShout); MyParameter para = new MyParameter("My test Parameter Name"); if (CatShout != null) { CatShout(this,para); } } void Test_CatShout(object sender, MyParameter para) { Console.WriteLine("This is my Test Delagate! Parameter's name is: {0}",para.Name); } static void Main() { Test c = new Test(); c.TestDelegate(); return; } }
三、下面的例子是一个没有使用事件并含有参数的委托
class clsDelegate { public delegate int simpleDelegate(int a, int b); public int addNumber(int a, int b) { return (a + b); } public int mulNumber(int a, int b) { return (a * b); } static void Main(string[] args) { clsDelegate clsDlg = new clsDelegate(); simpleDelegate addDelegate = new simpleDelegate(clsDlg.addNumber); simpleDelegate mulDelegate = new simpleDelegate(clsDlg.mulNumber); if (addDelegate != null && mulDelegate != null) { int addAns = addDelegate(10, 12); int mulAns = mulDelegate(10, 10); Console.WriteLine("addNum method using a delegate: {0}", addAns); Console.WriteLine("mulNum method using a delegate: {0}", mulAns); Console.Read(); } } }
四、匿名委托的使用
匿名委托是使用委托的另一种方式,使用匿名委托时,代码执行的不太快。编译器仍指定了一个方法,该方法只有一个指定的名称。在匿名方法内部不能访问不安全的代码,也不能在匿名方法外部使用ref和out参数。
//匿名委托 private delegate void TestDelegate2(int a); public void Eample2() { int a = 12; TestDelegate2 t = delegate(int x) { Console.WriteLine("output x : {0}", x); }; t(a); } static void Main() { Test c = new Test(); c.Eample2(); return; }
匿名委托示例2,跟上一个示例类似
class Program { delegate string delegateTest(string str); static void Main(string[] args) { string second = ",second"; delegateTest test = delegate(string para) { para += second; para += ",third"; return para; }; Console.WriteLine( test("first")); }
}
五、下面是两个稍微复杂的例子
1.无参数事件
class Program
{
static void Main(string[] args)
{
Cat cat = new Cat("small cat");
Mouse mouse1 = new Mouse("small mouse1");
Mouse mouse2 = new Mouse("small mouse2");
//将Mouse的run方法通过实例化委托Cat.CatShoutEventHandlerd登记到CatShout中。
cat.CatShout += new Cat.CatShoutEventHandler(mouse1.Run);
cat.CatShout += new Cat.CatShoutEventHandler(mouse2.Run);
cat.CatShout += new Cat.CatShoutEventHandler(cat_CatShout);
cat.Shout();
Console.ReadLine();
}
static void cat_CatShout()
{
Console.WriteLine("cat is coming ,mouse3 run");
}
}
public class Cat
{
//声明委托
public delegate void CatShoutEventHandler();
public event CatShoutEventHandler CatShout;
private string _name;
public Cat(string name)
{
this._name = name;
}
public void Shout()
{
Console.WriteLine("miao, I am {0}", _name);
//如果CatShout中有对象登记事件,则执行CatShout()
if (CatShout != null)
CatShout();
}
}
public class Mouse
{
private string _name;
public Mouse(string name)
{
this._name = name;
}
public void Run()
{
Console.WriteLine("Cat is coming, {0} run", _name);
}
}
2.有参数事件
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace weituo { class Class1 { static void Main(string[] args) { Cat cat = new Cat("small cat"); Mouse mouse1 = new Mouse("small mouse1"); Mouse mouse2 = new Mouse("small mouse2"); //将Mouse的run方法通过实例化委托Cat.CatShoutEventHandlerd登记到CatShout中。 cat.CatShout += new Cat.CatShoutEventHandler(mouse1.Run); cat.CatShout += new Cat.CatShoutEventHandler(mouse2.Run); cat.CatShout += new Cat.CatShoutEventHandler(cat_CatShout); cat.Shout(); Console.ReadLine(); } static void cat_CatShout(object sender, CatShoutEventArgs e) { Console.WriteLine("cat is coming ,mouse run"); } } public class CatShoutEventArgs : EventArgs { private string _name; public CatShoutEventArgs(string name) { this._name = name; } public string Name { get { return _name; } set { _name = value; } } } public class Cat { //声明委托 public delegate void CatShoutEventHandler(object sender, CatShoutEventArgs e); public event CatShoutEventHandler CatShout; private string _name; public Cat(string name) { this._name = name; } public void Shout() { Console.WriteLine("miao, I am {0}", _name); CatShoutEventArgs e = new CatShoutEventArgs(_name); //如果CatShout中有对象登记事件,则执行CatShout() if (CatShout != null) CatShout(this, e); } } public class Mouse { private string _name; public Mouse(string name) { this._name = name; } public void Run(object sender, CatShoutEventArgs args) { Console.WriteLine("Cat {0} is coming, {1} run", args.Name, _name); } } }
3、WPF中的事件
3.1 public Window1() { InitializeComponent(); this.Loaded += new RoutedEventHandler(Init); } void Init(object sender, RoutedEventArgs e) { button2.Click += new RoutedEventHandler(button2_Click); button3.Click += new RoutedEventHandler(button3Click); } void button3Click(object sender, RoutedEventArgs e) { MessageBox.Show("testbutton3"); } void button2_Click(object sender, RoutedEventArgs e) { MessageBox.Show("testbutton2"); }
3.2DispatcherTimer的使用. 集成到按指定时间间隔和指定优先级处理的 Dispatcher队列中的计时器。
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
this.Loaded += delegate
{
//处理函数
button2_Click();
timer.Stop();
};
timer.Start();
六、EventHandler泛型委托
class EventHandlerTest { public static void TestEventHandler() { HasEvent has = new HasEvent(); has.SampleEvent += new EventHandler<MyEventArgs>(has_SampleEvent); has.EventTest("work smart!"); has.EventTest("work hard!"); } static void has_SampleEvent(object sender, MyEventArgs e) { Console.WriteLine(e.Message); } } public class MyEventArgs:EventArgs { private string msg; public MyEventArgs(string message) { msg = message; } public string Message { get { return msg; } set { msg = value; } } } public class HasEvent { public event EventHandler<MyEventArgs> SampleEvent; public void EventTest(string str) { EventHandler<MyEventArgs> myEvent = SampleEvent; if (myEvent != null) { myEvent(this, new MyEventArgs(str)); } } }
作者:Work Hard Work Smart
出处:http://www.cnblogs.com/linlf03/
欢迎任何形式的转载,未经作者同意,请保留此段声明!