温习一下Delegate吧
这两天是刚到新公司的,我的一篇博客加密了因为它是我们公司的一个面试题,恕不再向外界明示。
都好几个周没有写过一行代码了,先熟悉一下,一个同事说再好好熟悉一下委托吧,于是我花了一个上午来写了几个关于委托的例子。
至于一些概念上的知识在网上已经有很多了,这里我只贴了一下我写的例子,有兴趣的朋友看一下,有不足或错误的地方指点出来!
这个练习是一个控制台程序,基于.NET4.0 C#语言:
关于委托的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestDelegate
{
class Program
{
static void Main(string[] args)
{
//-----------简单的委托与委托队列-------------
SayHello say=new SayHello(new BBG("Si yao min").SayHello);
say();
say = new BBG("张国荣").SayHello;
say();
say += new BBG("周杰伦").SayHello;
say += new BBG("李小龙").SayHello;
say();
say -= new BBG("李小龙").SayHello;
say -= new BBG("李大龙").SayHello;//去除委托的话如果里面没有这个
BBG lxl = new BBG("李小龙");
say += lxl.SayHello;
say += lxl.SayHello;//即使是同一对象的方法也能在一个委托中加入多次当调用的时候会依次调用
say();
//say();//执行到异常方法后也抛出异常
//---------在委托队列中加入静态类型方法--------
say += Printer.PrintOK;
//---------逐个调用委托中的方法--------
foreach (Delegate d in say.GetInvocationList())
{
try
{
d.Method.Invoke(lxl, null);
//第一个参数为调用这个方法的类如果是静态的类型也没有问题,作为静态类型不会再去查找它的调用者
//然而这种方法不能处理有异常的类型,这样就要使调用的方法中不能有任何的异常出现
}
catch (Exception e) { Printer.PrintMessage(e.Message); }
}
//---------在委托队列中加入抛出异常的委托类型方法--------
say += lxl.ThrowExceptionMethod;//加入一个异常到委托队列中
foreach (SayHello d in say.GetInvocationList())
{
try
{
d();//由于上面的类型为SayHello,所以用了这个类型作为d的类型
//这里就可以捕获调用方法中抛出的所有异常信息
}
catch (Exception e) { Printer.PrintMessage(e.Message); }
}
Console.WriteLine("目前有" + say.GetInvocationList().Count().ToString() + "个方法在Say中!");
//---------在委托中同步调用--------
AsynTest atest = AsynDelegateTest.StarWork;
Printer.PrintMessage("下面的方法要等5秒种以后才能继续...");
atest(5);
AsynDelegateTest.CompleteTask();
//---------在委托中异步调用方法(1)--------
AsyncCallback ac = new AsyncCallback(AsynDelegateTest.CompleteTask);
IAsyncResult iresult=atest.BeginInvoke(5,null, null);
Printer.PrintMessage("主线程暂停1秒期间打印Can do Other");
while (!iresult.IsCompleted)
{
System.Threading.Thread.Sleep(1000);
System.Console.WriteLine("Can do Other");
}
AsynDelegateTest.CompleteTask();
//---------在委托中异步调用方法(2)用回调函数来处理--------
Printer.PrintMessage("下面使用有回调函数的异步调用");
atest.BeginInvoke(5, ac, atest);
//
Printer.PrintMessage("下面用到的是事件来完成一个猫发现老鼠的事情处理");
Cat c = new Cat();
c.Name = "cat1";
Mouse m = new Mouse();
m.Name = "mouce1";
c.Noticer = new List<INotice> { m};
m.Noticer = c;
Bindings b = new Bindings();
b.c = c;
b.BindCat();
c.NoticeObject();
//
Printer.PrintMessage("下面是一个打印数字的方法!");
string inputchar=string.Empty;
int count;
GetNumber g ;
while (inputchar != "Q" && inputchar != "q")
{
if (int.TryParse(inputchar, out count))
{
g = Interval.GetDelegate(count);
if (g == null)
{
Printer.PrintMessage("请输入 2,3,4,6,Q 或q!");
}
else
{
Printer.PrintList<int>(g());
}
}
else
{
Printer.PrintMessage("请输入 2,3,4,6,Q 或q!");
}
inputchar = Console.ReadLine();
}
}
}
delegate List<int> GetNumber();
delegate void SayHello();
delegate void AsynTest(int needseconds);
//一个产生数字的类型
class NumberGame
{
private NumberGame()
{ }
private static List<int> Source = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
public static List<int> GetTopTwo()
{
return Source.Take<int>(2).ToList<int>();
}
public static List<int> GetTopThree()
{
return Source.Take<int>(3).ToList<int>();
}
public static List<int> GetTopFour()
{
return Source.Take<int>(4).ToList<int>();
}
public static List<int> GetTopSix()
{
return Source.Take<int>(6).ToList<int>();
}
}
//用一个中间类来得到不同的委托方法
class Interval
{
public static GetNumber GetDelegate(int count)
{
switch (count)
{
case 2:
return new GetNumber(NumberGame.GetTopTwo);
case 3:
return new GetNumber(NumberGame.GetTopThree);
case 4:
return new GetNumber(NumberGame.GetTopFour);
case 6:
return new GetNumber(NumberGame.GetTopSix);
default:
return null;
}
}
}
//用于学习静态方法委托
class Printer
{
public static void PrintList<T>(List<T> l)
{
foreach (var i in l)
{
Console.Write(i + "\t");
}
Console.WriteLine();
}
//
public static void PrintMessage(string msg)
{
Console.WriteLine(msg);
}
//
public static void PrintOK()
{
Console.WriteLine("OK");
}
}
//用于学习实例委托
class BBG
{
public void SayHello()
{
Printer.PrintMessage("hello everyone,I'm"+ Name);
}
public void ThrowExceptionMethod()
{
throw new Exception("Exception in ThrowExceptionMethod");
}
public string Name { get; set; }
public BBG()
{
}
public BBG(String name)
{
this.Name = name;
}
}
//用于异常调用
class AsynDelegateTest
{
public static void StarWork(int needseconds)
{
Printer.PrintMessage("Working...");
System.Threading.Thread.Sleep(needseconds*1000);
}
public static void CompleteTask()
{
Printer.PrintMessage("Done");
}
public static void CompleteTask(IAsyncResult ia)
{
//ia.AsyncState == null 在委托中的BeginInvoke方法中的最后一个参数如果是空那么它的AsyncState也就为空了
AsynTest t = ia.AsyncState as AsynTest;
//一定要调用这个方法,这样是为了终止异步线程
t.EndInvoke(ia);
Printer.PrintMessage("Done");
}
}
//
interface IObjectResponse
{
void Response();
}
interface INotice
{
void NoticeObject();
}
//
class MouseCatEventArgs : EventArgs
{
public MouseCatEventArgs()
{
Printer.PrintMessage("Noticing");
}
}
//delegate void ResponseHandler(object sender, MouseCatEventArgs e);
delegate void NoticeHandler(object sender, MouseCatEventArgs e);
class Cat:IObjectResponse,INotice
{
//public event ResponseHandler responseh;
public event NoticeHandler noticeh;
public string Name { get; set; }
public List<INotice> Noticer { get; set; }
public void Response()
{
Printer.PrintMessage("Cat:"+Name+" Crying");
}
public void NoticeObject()
{
OnNoticeObject();
}
public void OnNoticeObject()
{
if (noticeh != null)
{
noticeh(this, new MouseCatEventArgs());
}
}
}
public delegate void noticed();
//public delegate void responsed();
class Mouse : IObjectResponse, INotice
{
public event NoticeHandler noticeh;
//public event ResponseHandler responseh;
public noticed noticedel;
//public responsed resonsedel;
public string Name { get; set; }
public INotice Noticer { get; set; }
public void Response()
{
Printer.PrintMessage("Mouse:" + this.Name + " Running");
}
public void NoticeObject()
{
OnNoticeObject();
}
public void OnNoticeObject()
{
if (noticeh != null)
{
noticeh(this,new MouseCatEventArgs());
}
}
}
//
class Bindings
{
public Cat c { get; set; }
public void BindCat()
{
c.noticeh += delegate { Console.WriteLine(c.Name+" is comming !"); c.Noticer.ForEach(m=>m.NoticeObject()); };//事件机制也是一种解耦把对事件的处理放在别处来写
foreach (Mouse m in c.Noticer)
{
m.Noticer = c;
m.noticeh += delegate { Console.WriteLine("Wa Cat is comming !");m.Response() ; };//事件机制也是一种解耦把对事件的处理放在别处来写
m.noticedel += m.OnNoticeObject;
}
}
}
//
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestDelegate
{
class Program
{
static void Main(string[] args)
{
//-----------简单的委托与委托队列-------------
SayHello say=new SayHello(new BBG("Si yao min").SayHello);
say();
say = new BBG("张国荣").SayHello;
say();
say += new BBG("周杰伦").SayHello;
say += new BBG("李小龙").SayHello;
say();
say -= new BBG("李小龙").SayHello;
say -= new BBG("李大龙").SayHello;//去除委托的话如果里面没有这个
BBG lxl = new BBG("李小龙");
say += lxl.SayHello;
say += lxl.SayHello;//即使是同一对象的方法也能在一个委托中加入多次当调用的时候会依次调用
say();
//say();//执行到异常方法后也抛出异常
//---------在委托队列中加入静态类型方法--------
say += Printer.PrintOK;
//---------逐个调用委托中的方法--------
foreach (Delegate d in say.GetInvocationList())
{
try
{
d.Method.Invoke(lxl, null);
//第一个参数为调用这个方法的类如果是静态的类型也没有问题,作为静态类型不会再去查找它的调用者
//然而这种方法不能处理有异常的类型,这样就要使调用的方法中不能有任何的异常出现
}
catch (Exception e) { Printer.PrintMessage(e.Message); }
}
//---------在委托队列中加入抛出异常的委托类型方法--------
say += lxl.ThrowExceptionMethod;//加入一个异常到委托队列中
foreach (SayHello d in say.GetInvocationList())
{
try
{
d();//由于上面的类型为SayHello,所以用了这个类型作为d的类型
//这里就可以捕获调用方法中抛出的所有异常信息
}
catch (Exception e) { Printer.PrintMessage(e.Message); }
}
Console.WriteLine("目前有" + say.GetInvocationList().Count().ToString() + "个方法在Say中!");
//---------在委托中同步调用--------
AsynTest atest = AsynDelegateTest.StarWork;
Printer.PrintMessage("下面的方法要等5秒种以后才能继续...");
atest(5);
AsynDelegateTest.CompleteTask();
//---------在委托中异步调用方法(1)--------
AsyncCallback ac = new AsyncCallback(AsynDelegateTest.CompleteTask);
IAsyncResult iresult=atest.BeginInvoke(5,null, null);
Printer.PrintMessage("主线程暂停1秒期间打印Can do Other");
while (!iresult.IsCompleted)
{
System.Threading.Thread.Sleep(1000);
System.Console.WriteLine("Can do Other");
}
AsynDelegateTest.CompleteTask();
//---------在委托中异步调用方法(2)用回调函数来处理--------
Printer.PrintMessage("下面使用有回调函数的异步调用");
atest.BeginInvoke(5, ac, atest);
//
Printer.PrintMessage("下面用到的是事件来完成一个猫发现老鼠的事情处理");
Cat c = new Cat();
c.Name = "cat1";
Mouse m = new Mouse();
m.Name = "mouce1";
c.Noticer = new List<INotice> { m};
m.Noticer = c;
Bindings b = new Bindings();
b.c = c;
b.BindCat();
c.NoticeObject();
//
Printer.PrintMessage("下面是一个打印数字的方法!");
string inputchar=string.Empty;
int count;
GetNumber g ;
while (inputchar != "Q" && inputchar != "q")
{
if (int.TryParse(inputchar, out count))
{
g = Interval.GetDelegate(count);
if (g == null)
{
Printer.PrintMessage("请输入 2,3,4,6,Q 或q!");
}
else
{
Printer.PrintList<int>(g());
}
}
else
{
Printer.PrintMessage("请输入 2,3,4,6,Q 或q!");
}
inputchar = Console.ReadLine();
}
}
}
delegate List<int> GetNumber();
delegate void SayHello();
delegate void AsynTest(int needseconds);
//一个产生数字的类型
class NumberGame
{
private NumberGame()
{ }
private static List<int> Source = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
public static List<int> GetTopTwo()
{
return Source.Take<int>(2).ToList<int>();
}
public static List<int> GetTopThree()
{
return Source.Take<int>(3).ToList<int>();
}
public static List<int> GetTopFour()
{
return Source.Take<int>(4).ToList<int>();
}
public static List<int> GetTopSix()
{
return Source.Take<int>(6).ToList<int>();
}
}
//用一个中间类来得到不同的委托方法
class Interval
{
public static GetNumber GetDelegate(int count)
{
switch (count)
{
case 2:
return new GetNumber(NumberGame.GetTopTwo);
case 3:
return new GetNumber(NumberGame.GetTopThree);
case 4:
return new GetNumber(NumberGame.GetTopFour);
case 6:
return new GetNumber(NumberGame.GetTopSix);
default:
return null;
}
}
}
//用于学习静态方法委托
class Printer
{
public static void PrintList<T>(List<T> l)
{
foreach (var i in l)
{
Console.Write(i + "\t");
}
Console.WriteLine();
}
//
public static void PrintMessage(string msg)
{
Console.WriteLine(msg);
}
//
public static void PrintOK()
{
Console.WriteLine("OK");
}
}
//用于学习实例委托
class BBG
{
public void SayHello()
{
Printer.PrintMessage("hello everyone,I'm"+ Name);
}
public void ThrowExceptionMethod()
{
throw new Exception("Exception in ThrowExceptionMethod");
}
public string Name { get; set; }
public BBG()
{
}
public BBG(String name)
{
this.Name = name;
}
}
//用于异常调用
class AsynDelegateTest
{
public static void StarWork(int needseconds)
{
Printer.PrintMessage("Working...");
System.Threading.Thread.Sleep(needseconds*1000);
}
public static void CompleteTask()
{
Printer.PrintMessage("Done");
}
public static void CompleteTask(IAsyncResult ia)
{
//ia.AsyncState == null 在委托中的BeginInvoke方法中的最后一个参数如果是空那么它的AsyncState也就为空了
AsynTest t = ia.AsyncState as AsynTest;
//一定要调用这个方法,这样是为了终止异步线程
t.EndInvoke(ia);
Printer.PrintMessage("Done");
}
}
//
interface IObjectResponse
{
void Response();
}
interface INotice
{
void NoticeObject();
}
//
class MouseCatEventArgs : EventArgs
{
public MouseCatEventArgs()
{
Printer.PrintMessage("Noticing");
}
}
//delegate void ResponseHandler(object sender, MouseCatEventArgs e);
delegate void NoticeHandler(object sender, MouseCatEventArgs e);
class Cat:IObjectResponse,INotice
{
//public event ResponseHandler responseh;
public event NoticeHandler noticeh;
public string Name { get; set; }
public List<INotice> Noticer { get; set; }
public void Response()
{
Printer.PrintMessage("Cat:"+Name+" Crying");
}
public void NoticeObject()
{
OnNoticeObject();
}
public void OnNoticeObject()
{
if (noticeh != null)
{
noticeh(this, new MouseCatEventArgs());
}
}
}
public delegate void noticed();
//public delegate void responsed();
class Mouse : IObjectResponse, INotice
{
public event NoticeHandler noticeh;
//public event ResponseHandler responseh;
public noticed noticedel;
//public responsed resonsedel;
public string Name { get; set; }
public INotice Noticer { get; set; }
public void Response()
{
Printer.PrintMessage("Mouse:" + this.Name + " Running");
}
public void NoticeObject()
{
OnNoticeObject();
}
public void OnNoticeObject()
{
if (noticeh != null)
{
noticeh(this,new MouseCatEventArgs());
}
}
}
//
class Bindings
{
public Cat c { get; set; }
public void BindCat()
{
c.noticeh += delegate { Console.WriteLine(c.Name+" is comming !"); c.Noticer.ForEach(m=>m.NoticeObject()); };//事件机制也是一种解耦把对事件的处理放在别处来写
foreach (Mouse m in c.Noticer)
{
m.Noticer = c;
m.noticeh += delegate { Console.WriteLine("Wa Cat is comming !");m.Response() ; };//事件机制也是一种解耦把对事件的处理放在别处来写
m.noticedel += m.OnNoticeObject;
}
}
}
//
}


浙公网安备 33010602011771号