近日一直在关注如何使用委托,但是使用方法到是好理解,但是如何应用的恰到好处却一直困扰着我。下面是在网上看到的一个例子,希望已经对委托理解很好的人帮忙指点一下。
using System; class MathClass
{
public static int max(int a,int b)
{return(a>b?a:b);} public static int min(int a,int b)
{return(a-b);} public static int sub(int a,int b)
{return (a+b);} public static int minus(int a,int b)
{return (a-b);}
}class Handler
{
private delegate int Calculation(int a, int b);
private static Calculation[] myCalculation=new Calculation[3];
public static void EventHandler(int i,int a,int b)
{
switch (i)
{
case 1:
myCalculation[0]=new Calculation(MathClass.max);
myCalculation[1]=new Calculation(MathClass.min);
Console.WriteLine(myCalculation[0](a,b));
Console.WriteLine(myCalculation[1](a,b));
break;
case 2:
myCalculation[0]=new Calculation(MathClass.sub);
myCalculation[1]=new Calculation(MathClass.minus);
Console.WriteLine(myCalculation[0](a,b));
Console.WriteLine(myCalculation[1](a,b));
break;
default:
return;
}
}
}class Test
{
static void Main()
{
Handler.EventHandler(1,10,3);
Handler.EventHandler(2,10,3);
}
}
上面的例子我用 SELECT-CASE 我感觉会更容易实现或理解。如果想让调用者更加明确,我可以在声明一个enum,为什么还用这么麻烦的委托呢? 可能我对委托的理解还有些偏差,请高手赐教,谢。
using System; class MathClass
{
public static int max(int a,int b)
{return(a>b?a:b);} public static int min(int a,int b)
{return(a-b);} public static int sub(int a,int b)
{return (a+b);} public static int minus(int a,int b)
{return (a-b);}
}class Handler
{
private delegate int Calculation(int a, int b);
private static Calculation[] myCalculation=new Calculation[3];
public static void EventHandler(int i,int a,int b)
{
switch (i)
{
case 1:
myCalculation[0]=new Calculation(MathClass.max);
myCalculation[1]=new Calculation(MathClass.min);
Console.WriteLine(myCalculation[0](a,b));
Console.WriteLine(myCalculation[1](a,b));
break;
case 2:
myCalculation[0]=new Calculation(MathClass.sub);
myCalculation[1]=new Calculation(MathClass.minus);
Console.WriteLine(myCalculation[0](a,b));
Console.WriteLine(myCalculation[1](a,b));
break;
default:
return;
}
}
}class Test
{
static void Main()
{
Handler.EventHandler(1,10,3);
Handler.EventHandler(2,10,3);
}
}
上面的例子我用 SELECT-CASE 我感觉会更容易实现或理解。如果想让调用者更加明确,我可以在声明一个enum,为什么还用这么麻烦的委托呢? 可能我对委托的理解还有些偏差,请高手赐教,谢。
系统类(或者已提供的公共类)提供一种委托类型,且在某个方法中当作参数传给自己调用,这个参数供应用开发程序员去提供。
这样系统类就是在调用一个只知道签名而没有实现的方法,这个实现过程就可以由你(应用开发程序员)来决定。
这当然就不是case可以相提并论的了。确参考一下回调(异步回调),事件,和线程吧。
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ObjectPooling(MinPoolSize=4, MaxPoolSize=4)]
[EventTrackingEnabled] public class MyComPlus:ServicedComponent
{
public delegate void TranSactionProcess(DataSet arg1,DataSet arg2);
public TranSactionProcess Process;
public MyComPlus()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
protected override bool CanBePooled()
{
return true;
}
[AutoComplete]
public void RunTranSaction(DataSet arg1,DataSet arg2)
{
return Process(arg1,arg2);
}
}里面的RunTranSaction函数就是使用事务的函数。这样我在自己的类中如果要使用事务的话就可以使用这个代理了public class MyClass
{
....
//下面的方法需要用到事务
public void TransInsertPoData( DataSet ds1,DataSet ds2)
{ MyDataAccess dal=new MyDataAccess();
try
{
dal.Update(ds1);
dal.Update(ds2);
}
}
//使用下面的方法来实现事务
public InsertPoData( DataSet ds1,DataSet ds2)
{
MyComPlus complus=new EleadComPlus();
complus.Process+=new MyComPlus.TranSactionProcess(TransInsertPoData);
rcomplus.RunTranSaction(ds1,ds2);
}
}
你命令小王,如果小张玩游戏,则小王扣去小张500元钱。这就是现实中的委托。实际上,在写程序中,程序员就是老板,小张和小王就是两个对象。小张玩游戏是一个方法,小张还有一个游戏事件,他玩游戏激发这个事件。而小王就是事件处理对象,他负责把小张的钱扣除500。所以,委托有如下几个要素:
1 激发事件的对象--就是小张
2 处理对象事件的对象--就是小王
3 定义委托,就是你让小王监视小张。如果这三个要素都满足的话,则你就写出了一个完整事件的处理。下面有个例子:在vs.net2003 C#控制台应用程序编辑运行成功:
using System;namespace CSharpConsole
{
public class 场景
{
[STAThread]
public static void Main(string[] args)
{
Console.WriteLine("场景开始了....");
// 生成小王
小王 w = new 小王();
// 生成小账
小张 z = new 小张(); // 指定监视
z.PlayGame += new PlayGameHandler(w.扣钱);
// 开始玩游戏
z.玩游戏(); Console.WriteLine("场景结束...");
Console.ReadLine();
}
}
// 负责扣钱的人
public class 小王
{
public 小王()
{
Console.WriteLine("生成小王...");
} public void 扣钱(object sender,EventArgs e)
{
Console.WriteLine("小王:好小子,上班时间胆敢玩游戏...");
Console.WriteLine("小王:看看你小子有多少钱...");
小张 f = (小张)sender;
Console.WriteLine("小张的钱: " + f.钱.ToString());
Console.WriteLine("开始扣钱......");
System.Threading.Thread.Sleep(500);
f.钱 = f.钱 - 500;
Console.WriteLine("扣完了....现在小张还剩下:" + f.钱.ToString());
}
} // 如果玩游戏,则引发事件
public class 小张
{
// 先定义一个事件,这个事件表示“小张”在玩游戏。
public event PlayGameHandler PlayGame;
// 保存小张钱的变量
private int m_Money; public 小张()
{
Console.WriteLine("生成小张....");
m_Money = 1000; // 构造函数,初始化小张的钱。
} public int 钱 // 此属性可以操作小张的钱。
{
get
{
return m_Money;
}
set
{
m_Money = value;
}
} public void 玩游戏()
{
Console.WriteLine("小张开始玩游戏了.....");
Console.WriteLine("小张:CS好玩,哈哈哈! 我玩.....");
System.Threading.Thread.Sleep(500);
System.EventArgs e = new EventArgs();
OnPlayGame(e);
} protected virtual void OnPlayGame(EventArgs e)
{
if(PlayGame != null)
{
PlayGame(this,e);
}
}
} // 定义委托处理程序
public delegate void PlayGameHandler(object sender,System.EventArgs e);}
====ww.madeinwuxi.com====
http://www.madeinwuxi.com
一个常见的运用就是窗体的关闭,但往往只关闭窗体是不能满足要求的。
在很多情况下关闭窗体前需要做什么,关闭后又需要做什么。
所以在winform下关闭窗体前后分别会触发closing,closed两个事件。
通过这种方法能够更好地把功能组合起来。
对于COM+的那个例提一个小意见,代码如下
[AutoComplete]
public void RunTranSaction(parans IDataAccess[] access)
{
if(access !=null && access.length >0)
foreach(IDataAccess item in access)
item.Execute();
}通过接口分离可以让功能更灵活。
或者能给一个更清晰明了的例子(也就是这个例子不是很复杂,但是不用委托就不行,或者用委托以后要比不用有明显的优势) ]
那我把 http://community.csdn.net/Expert/topic/4465/4465328.xml?temp=.6670038 这里的回复重新发一遍好了……外加一点修正。
------------------例如有一个方法,它的作用是从来源A获取信息然后发布到目标B,但是它不会处理信息。它的工作是这个样子的:while (还没下班) {
// 获取信息
// 获取信息
// 获取信息
// 获取信息 // 处理信息——我不知该怎么处理 // 发布信息
// 发布信息
// 发布信息
// 发布信息
}它就可以将处理信息那里抽象成一个委托,这个委托的输入是获取回来的信息,输出是经过处理可以发布的信息:
public delegate string/*输出*/ ProcessInfoDelegate(string rawMessage)/*输入*/这样,方法就可以写成public void TransferInfo(A source, ProcessInfoDelegate how, B destination)
{
while (!TimeToGoHome()) {
string msg;
// ...
// 获取信息中
// ... if (how != null) // 如果别人提供了信息处理方法
msg = how(msg); // 就委托别人做信息处理工作 // ...
// 发布信息中
// ...
}
}那么,如果有一个类需要用这个方便的方法,它就先定义它期待的信息处理方法,例如
class User
{
private string MyProcessor(string input)
{
return input.Substring(2); // 不要最前面两个字符
}然后调用方法:
public void Do()
{
....
ClassName.TransferInfo(src,
new ProcessInfoDelegate(MyProcessor), // 包装委托变量
dest);
}
}
ThreadStart委托就可以包装你的方法,传递给线程。让线程来执行。所以委托就是“方法引用”
class 人类
{
//构造函数代码略
public void 好()
}
//分别new 一个人类的实例:我、他 (代码略 )public void delegate 好(); 好 他好=new 好(他.好)
好 我好=new 好(我.好)
好 大家好=他好+我好嘿嘿,汇仁肾保:)