一、简述:

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

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

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

二、定义:

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

  在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#.NET开源项目、机器学习、商务智能

    所以原谅我,不能把所有的都发上来,太杂了,反而不好. 1..NET时间周期处理组件 这个组件很小,主要是对时间日期,特别是处理时间间隔以及时间范围非常方便.虽然.NET自带了时间日期的部分功能,但可能 ...

  2. 进程通信之一 使用WM_COPYDATA C++及C#实现 z

    原文地址:http://blog.csdn.net/morewindows/article/details/6804157 进程间通信最简单的方式就是发送WM_COPYDATA消息.本文提供C++及C ...

  3. static用法详解

    一. 面向过程程序设计 1.静态全局变量 在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量.我们先举一个静态全局变量的例子,如下: //Example 1 #include & ...

  4. Python脚本控制的WebDriver 常用操作 <二十三> wait

    测试用例场景 Wait类的使用场景是在页面上进行某些操作,然后页面上就会出现或隐藏一些元素,此时使用Wait类的until方法来等待这些效果完成以便进行后续的操作.另外页面加载时有可能会执行一些aja ...

  5. 【树莓PI】下载机

    sudo app-get install ntfs-3g  读写ntfs格式的磁盘 mount -t ntfs /dev/sda4 /mnt/usb -o nls=utf8,umask=0 fdisk ...

  6. bzoj 1095 [ZJOI2007]Hide 捉迷藏(括号序列+线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1095 [题意] 给定一棵树,树上颜色或白或黑而且可以更改,多个询问求最远黑点之间的距离 ...

  7. 【转载】如何在C语言中调用shell命令

    转载自:http://blog.csdn.net/chdhust/article/details/7951576 如何在C语言中调用shell命令 在linux操作系统中,很多shell命令使用起来非 ...

  8. 【Hadoop代码笔记】目录

    整理09年时候做的Hadoop的代码笔记. 开始. [Hadoop代码笔记]Hadoop作业提交之客户端作业提交 [Hadoop代码笔记]通过JobClient对Jobtracker的调用看详细了解H ...

  9. 关于Java Collections API您不知道的5件事,第2部分

    注意可变对象 java.util 中的 Collections 类旨在通过取代数组提高 Java 性能.如您在 第 1 部分 中了解到的,它们也是多变的,能够以各种方 式定制和扩展,帮助实现优质.简洁 ...

  10. SQL2008--行号的得到

    WITH DataTable AS( select *, ROW_NUMBER() OVER(order by ID) as Rowno from (select * from UserInfo) a ...