一、简述:

  委托对与我们编程人员来说,一点都不陌生,在实际工作过程中,或多或少都应该是接触过

  但是对与编程新手来说,对与委托的理解和使用应该还是一个坎,但是只要理解清楚了,这个坎也就过去了。

  最近也经常有人在问关于委托的使用的相关问题,在此我花点时间,对与委托的个人理解进行一个总结,希望能够给大家有所帮助作用。

二、定义:

  委托,其实在我们日常生活中,也经常用到委托的,比如:律师其实就是充当了一个委托的角色,当事人委托律师在法庭上对其诉讼辩护。

  在c#中,委托简单的理解就是将一个方法以参数的形式传递到另外一个方法中去,有点类似于c++中的指针的概念。

三、实现委托的步骤:

  在委托定义的时候,我们只需要定义一个结构体,至于具体的实现,需要在具体的委托方法中来实现。

  实现委托的步骤,我总结如下:

  其一、定义:要声明一个委托的结构体:delegate void Mydelegate(type1 para1,type2 para2);

  其二、声明:声明就是要声明一个委托变量:Mydelegate myDel;

  其三、实例化:就是要对声明的委托对象实例化具体的委托方法:myDel=new Mydelegate(obj.InstanceMethod);

  其四、参数传递:简单的理解,就是将委托以一个参数的形式传递给一个方法:MyMethod(myDel);

  其五、委托方法执行:这个和普通方法实现调用一样,就是在方法MyMethod里面调用执行委托的方法:myDel(obj.InstanceMethod)

四、使用

    委托的使用,根据平时的开经验,委托其实在实际的使用中,有两种场景:

   其一、同步使用:同步执行委托,阻塞主流程(和平时的方法执行效果一样)

namespace MyCalculat
{
/// <summary>
/// 定义一个委托
/// </summary>
/// <param name="num1">阐述1</param>
/// <param name="num2">参数2</param>
/// <returns>处理结果</returns>
public delegate int MyDelegate(int num1, int num2); /// <summary>
/// Calculat类
/// </summary>
public class Calculat
{
public int Calcul(int num1,int num2,int type ) {
MyDelegate myDelegate;
switch (type) {
case :
myDelegate = new MyDelegate(this.Add);
break;
case :
myDelegate = new MyDelegate(this.Reduce);
break;
////
//// 其他逻辑
////
default:
myDelegate = new MyDelegate(this.Add);
break;
}
 return this.CalculOpert(myDelegate,num1, num2); 
} /// <summary>
/// 计算具体逻辑处理
/// </summary>
/// <param name="calDel">MyDelegate计算委托变量</param>
/// <param name="num1">参数1</param>
/// <param name="num2">参数2</param>
/// <returns>计算处理结果</returns>
public int CalculOpert(MyDelegate calDel, int num1, int num2)
{
////
//// 其他业务逻辑处理
//// //// 委托调用处理--同步调用
return calDel.Invoke(num1,num2);
} /// <summary>
/// 相加
/// </summary>
/// <param name="num1">参数1</param>
/// <param name="num2">参数2</param>
/// <returns>结果</returns>
public int Add(int num1, int num2) {
return num1 + num2;
} /// <summary>
/// 相法
/// </summary>
/// <param name="num1">参数1</param>
/// <param name="num2">参数2</param>
/// <returns>结果</returns>
public int Reduce(int num1, int num2)
{
return num1 - num2;
}
}
}

   其二、异步使用:不阻塞主流程的执行,异步线程去执行委托方法里面的逻辑

namespace MyCalculat
{
/// <summary>
/// 定义一个委托
/// </summary>
/// <param name="num1">阐述1</param>
/// <param name="num2">参数2</param>
/// <returns>处理结果</returns>
public delegate int MyDelegate(int num1, int num2); /// <summary>
/// Calculat类
/// </summary>
public class AcyCalculat
{
public void Calcul(int num1, int num2, int type)
{
MyDelegate myDelegate;
switch (type)
{
case :
myDelegate = new MyDelegate(this.Add);
break;
case :
myDelegate = new MyDelegate(this.Reduce);
break;
////
//// 其他逻辑
////
default:
myDelegate = new MyDelegate(this.Add);
break;
} this.CalculOpert(myDelegate,num1,num2) ;
} /// <summary>
/// 计算具体逻辑处理
/// </summary>
/// <param name="calDel">MyDelegate计算委托变量</param>
/// <param name="num1">参数1</param>
/// <param name="num2">参数2</param>
/// <returns>计算处理结果</returns>
public void CalculOpert(MyDelegate calDel, int num1, int num2)
{
////
//// 其他业务逻辑处理
//// //// 委托调用处理--异步调用 //// 异步执行完毕后,无需回调方法
calDel.BeginInvoke(num1, num2, null, null);
//// 异步执行完毕后,有回调方法
calDel.BeginInvoke(num1, num2, new AsyncCallback(this.AsyncOpert), new int[] { num1, num2 }); } /// <summary>
/// 处理异步执行结果逻辑
/// </summary>
/// <param name="resout">异步处理结果</param>
public void AsyncOpert(IAsyncResult resout)
{
MyDelegate myDel = (MyDelegate)((AsyncResult)resout).AsyncDelegate;
//// 获取异步处理结果
int res = myDel.EndInvoke(resout); //// 委托方法参数
int[] lisNum = (int[])resout.AsyncState; if (res > )
{
/////
///// 业务逻辑处理
/////
}
else
{
/////
///// 业务逻辑处理
/////
}
} /// <summary>
/// 相加
/// </summary>
/// <param name="num1">参数1</param>
/// <param name="num2">参数2</param>
/// <returns>结果</returns>
public int Add(int num1, int num2)
{
//// 其它业务逻辑处理
return num1 + num2;
} /// <summary>
/// 相法
/// </summary>
/// <param name="num1">参数1</param>
/// <param name="num2">参数2</param>
/// <returns>结果</returns>
public int Reduce(int num1, int num2)
{
//// 其它业务逻辑处理
return num1 - num2;
}
}
}

  委托结合反射的使用:这中情况的使用场景是:当不同的委托其对于的参数个数或者参数类型不尽相同,那么这时候就在调用委托方法时,就不能简简单单的调用执行

    这种情况在实际工作中场景举例:比如我们在使用缓存机制时候,都要使用到委托通反射相结合使用。

    

   /// <summary>
/// Calculat类
/// </summary>
public class Calculat
{
/// <summary>
/// 获取产品详情
/// </summary>
/// <param name="proKeyID">产品ID</param>
/// <returns>获取结果</returns>
public string GetProInfor(string proKeyID)
{
string proInfor = string.Empty; proInfor = ChachHelp.GetBusData<string>(new Func<string, string>(new ProBuss().GetProInfor), "proDetile" + proKeyID, , proKeyID); return proInfor;
} /// <summary>
/// 获取用户常用产品
/// </summary>
/// <param name="userID">用户ID</param>
/// <param name="cout">获取条数</param>
/// <returns>获取结果</returns>
public string GetCommonProInto(string userID, int cout)
{
string commonProInto = string.Empty; commonProInto = ChachHelp.GetBusData<string>(new Func<string, int, string>(new ProBuss().GetCommonProInto), "commonProInto" + userID, , userID, cout); return commonProInto;
}
} /// <summary>
/// 产品相关操作的业务逻辑处理
/// </summary>
public class ProBuss
{
/// <summary>
/// 获取产品详情
/// </summary>
/// <param name="proKeyID">产品ID</param>
/// <returns>获取结果</returns>
public string GetProInfor(string proKeyID)
{
string proInfor = string.Empty; ////---
//// 具体产品详情的逻辑处理
///--- return proInfor;
} /// <summary>
/// 获取用户常用产品
/// </summary>
/// <param name="userID">用户ID</param>
/// <param name="cout">获取条数</param>
/// <returns>获取结果</returns>
public string GetCommonProInto(string userID, int cout)
{
string commonProInto = string.Empty; ////---
//// 获取用户常用产品的逻辑处理
///--- return commonProInto;
}
} /// <summary>
/// 缓存操作类
/// </summary>
public class ChachHelp
{
/// <summary>
/// 获取缓存方法
/// </summary>
/// <typeparam name="T">返回数据类型</typeparam>
/// <param name="dele">数据获取方法</param>
/// <param name="cacheKey">缓存建</param>
/// <param name="cacheDuration">缓存时间</param>
/// <param name="objs">具体的参数集合</param>
/// <returns>获取结果</returns>
public static T GetBusData<T>(Delegate dele, string cacheKey, int cacheDuration, params object[] objs)
{
object obj = null; try
{
///// obj =//// 具体调用缓存获取数据方法;
}
catch (Exception ex)
{
//// 吃掉异常
} //// 如果缓存中没有获取到数据,那么就直接通过方法获取数据
if (obj == null)
{
string assemblyName = dele.Target.GetType().Assembly.FullName;
string typeName = dele.Target.GetType().FullName;
object instance = Assembly.Load(assemblyName).CreateInstance(typeName);
MethodInfo methodInfo = dele.Method; obj = methodInfo.Invoke(instance, objs);
if (obj != null)
{
//// 在获取到数据后,应当将获取到数据,存储记得到缓存中去
//// 缓存存储具体方法逻辑
}
} //// 类型转换,将obj转换为对应的数据类型
//// 此处先简略的直接用强制转换一波
T tobj = (T)obj;
return tobj;
}
}

五、小结:

  从上面的委托代码中可以发现,引入委托后,编程人员可以把方法的引用封装在委托对象中

  (把过程的调用转化为对象的调用,充分体现了委托加强了面向对象编程的思想。),

  然后把委托对象传递给需要引用方法的代码,这样在编译的过程中我们并不知道调用了哪个方法,

  这样一来,C#引入委托机制后,使得方法声明和方法实现的分离,充分体现了面向对象的编程思想。

关于c#中委托使用小结的更多相关文章

  1. C#不用union,而是有更好的方式实现 .net自定义错误页面实现 .net自定义错误页面实现升级篇 .net捕捉全局未处理异常的3种方式 一款很不错的FLASH时种插件 关于c#中委托使用小结 WEB网站常见受攻击方式及解决办法 判断URL是否存在 提升高并发量服务器性能解决思路

    C#不用union,而是有更好的方式实现   用过C/C++的人都知道有个union,特别好用,似乎char数组到short,int,float等的转换无所不能,也确实是能,并且用起来十分方便.那C# ...

  2. 详解Objective-C中委托和协议

    Objective-C委托和协议本没有任何关系,协议如前所述,就是起到C++中纯虚类的作用,对于“委托”则和协议没有关系,只是我们经常利用协议还实现委托的机制,其实不用协议也完全可以实现委托. AD: ...

  3. MVC图片上传详解 IIS (安装SSL证书后) 实现 HTTP 自动跳转到 HTTPS C#中Enum用法小结 表达式目录树 “村长”教你测试用例 引用provinces.js的三级联动

    MVC图片上传详解   MVC图片上传--控制器方法 新建一个控制器命名为File,定义一个Img方法 [HttpPost]public ActionResult Img(HttpPostedFile ...

  4. C#中委托和事件的区别实例解析

    这篇文章主要介绍了C#中委托和事件的区别,并分别以实例形式展示了通过委托执行方法与通过事件执行方法,以及相关的执行流程与原理分析,需要的朋友可以参考下 本文实例分析了C#中委托和事件的区别,分享给大家 ...

  5. C#中委托和事件

    目 录 将方法作为方法的参数 将方法绑定到委托 更好的封装性 限制类型能力 范例说明 Observer 设计模式简介 实现范例的Observer 设计模式 .NET 框架中的委托与事件 为什么委托定义 ...

  6. c#中委托和事件(转)

    C# 中的委托和事件 引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真 ...

  7. C#中委托

    委托是一种安全地封装方法的类型,它与 C 和 C++ 中的函数指针类似.与 C 中的函数指针不同,委托是面向对象的.类型安全的和保险的.一个委托类型是代表与特定参数列表和返回类型的方法的引用类型.实例 ...

  8. C#中委托的理解

    请注意,这只是个人关于C#中委托的一点点理解,参考了一些博客,如有不周之处,请指出,谢谢! 委托是一种函数指针,委托是方法的抽象,方法是委托的实例.委托是C#语言的一道坎,明白了委托才能算是C#真正入 ...

  9. 180531-Spring中JavaConfig知识小结

    原文链接:Spring中JavaConfig知识小结/ Sring中JavaConfig使用姿势 去掉xml的配置方式,改成用Java来配置,最常见的就是将xml中的 bean定义, scanner包 ...

随机推荐

  1. (一)学习C#之浮点类型float小结

    类型:float 大小:32位 范围a:±3.4E38  MSDNhttp://msdn.microsoft.com/zh-cn/library/b1e65aza.aspx 范围b: ±1.5E45~ ...

  2. uboot里读sd卡内容

    1. sd卡升级命令 mmcinit 0 fatload mmc 0:1 0 uzImage.bin 80000 fatload mmc 0:1 1000000 initrd.gz 580000 bo ...

  3. Balanced Numbers(数位+状压)

    题意:求给定区间,一个数的数位上每个奇数出现偶数次,每个偶数出现奇数次,这样数的个数 分析:先考虑状态,但总是想不全,所以要把状态压缩一下,用三进制,0 该数不放  1 放了奇数次 2放了偶数次 dp ...

  4. iOS7适配之设计篇

    (注:文章简要翻译自 Apple <iOS 7 UI Transition Guide>,由于该文档为开发者预览版,并非最终文档,所以 iOS7 正式上线可能有部分不同) 准备工作 iOS ...

  5. as3+java+mysql(mybatis) 数据自动工具(五)

    现在介绍常量的配置,主要用于客户端(as3)与服务端(java)之间的常量同步,比如错误码.请求标识等 配置格式: <macros name="Macros" groupSt ...

  6. winform窗体间利用委托传值(一)

    前台:在winform窗体Form1放入pictureBox1 后台代码: namespace 点击小图变成大图 { public delegate void ClickDelegateHander( ...

  7. CVTE面试经历

    CVTE也算一般的公司,很偏,不想说.我重点说一下面试的过程,我面试的C++程序开发工程师. 1.自我介绍自己的基本情况. 2.首先问你了解C++的面向对象么,他有哪些主要内容.对面向对象中的多态性你 ...

  8. 取小数点后三位的方法(js)

    使用js取小数点后三位的方法,我觉得这个方法最好 Math.round(num*100)/100 还有其他方法: http://hi.baidu.com/yansueh/item/f026d8d759 ...

  9. 设备扩展(DEVICE_EXTENSION)

    原文链接:http://blog.csdn.net/hazy/article/details/481705 WDM中的结构   ---设备扩展 设备扩展(DEVICE_EXTENSION)是与设备对象 ...

  10. wuzhicms页面报错 Notice 错误,如何关闭错误显示!

    错误类型类似: PHP Notice: Use of undefined constant E_DEPRECATED - assumed 'E_DEPRECATED' in D:\freehost\3 ...