一、委托基础

  1.什么是委托

  委托(Delegate) 是存有对某个方法的引用的一种引用类型变量,用关键字delegate申明,实现相同返回值和参数的函数的动态调用,提供了对方法的抽象。

  委托(Delegate)特别用于实现事件回调方法。所有的委托(Delegate)都派生自 System.Delegate 类。

  2.声明委托

  委托声明后决定了该委托可以引用的方法。

   public delegate string MyDelegate(int i);

  上面声明的委托可以用于引用任何返回值为string类型并且参数为一个int类型的任意方法名的方法,例如下面这个:

  public static string GetStr(int i){return i.ToString();}

  所以委托的声明格式为:访问修饰符+delegate+返回类型+类型名+参数。

  3.初始化委托变量以及赋值

  声明了委托类型后,和string、int等类型一样需要声明变量才能使用。对于初始化变量的赋值有两种方式:

  (1)new实例化赋值

  和一般的类实例化一样,在构造函数中传入方法名即可。

  MyDelegate mydelegate = new MyDelegate(GetStr);

  (2)直接赋值

  由于方法名称和相应的委托之间存在隐身转换,所以可以等于号赋值。

  MyDelegate mydelegate = GetStr;

  以上例子都是直接将方法名赋值给委托变量的,这是因为方法由static修饰。对于非静态的变量还是需要实例化使用,如下:

  MyDelegate mydelegate = new People().GetStr;

  由于委托是引用类型,用 '=' 重新赋值后会改变方法的引用地址,下述例子也继续使用静态方法。

  4.多播委托

  委托对象可以通过 ‘+’ 运算法进行组合,一个合并委托调用所组合的委托的所有指向方法引用地址,合并的委托必须是相同类型的。不仅是对象可以组合,通过 '+' 运算符可以让委托变量对方法自增。

  (1)委托对象组合

  MyDelegate mydelegate1 = GetStr;
  MyDelegate mydelegate2 = GetStr;
  MyDelegate mydelegate3 = mydelegate1 + mydelegate2;

  (2)自增

  MyDelegate mydelegate = GetStr;
  mydelegate += GetStr;

  有增自然有减,可以通过 ‘-’ 运算符进行方法引用地址的剔除,如果有多个同样的方法,只删除其中一个。

  5.匿名方法

  我们之前的方法都是事先声明好了的,然后使用方法名。但是有时候我们不想要声明新方法,因为这个是一个临时的方法。那么就可以用在c# 2.0版本引入的匿名方法,或者是3.0以后版本的lambda表达式。

  匿名方法使用的也是delegate关键字,不需要定义返回类型,格式为: delegate (传入参数) {执行语句},如下:

  MyDelegate mydelegate = delegate(int i) { return i.ToString(); };

  lambda表达式简化了匿名方法的书写,去掉了delegate关键字并加入 '=>' 运算符:

  MyDelegate mydelegate = (int i) => { Console.WriteLine(i.ToString()); };

  6.委托调用

  委托的调用和方法的调用差不多,因为委托声明的时候参数和返回值都已经确定了,所有加入委托调用列表的方法都是一样的,所以当委托调用的时候所有方法会依次执行。多播委托的情况下会返回最后一个有返回值的方法结果。但是要注意委托变量是否为空,空的执行会报错。

  if(mydelegate != null)
  mydelegate();

  7.泛型委托 

  泛型委托的加入使委托的使用更加方便,简化我们的代码。常用的泛型委托有两种:Action和Func,他们的使用和一般的委托差不多,帮我们省去了声明的哪一步。

  Action是无返回值的委托,封装了从无参数到16个参数的委托。

  Action action1 = () => { Console.WriteLine("无参的情况"); };
  Action<int> action = (int i) => { Console.WriteLine(i.ToString()); };
  action += (int i) => { Console.WriteLine((i+).ToString()); };
if (action != null)
  action();

  Func是有返回参数,所以格式是Fun<T t1,.....,TResult result>,这个返回类型为最后一个参数,并且是必须的,传入参数类型可以没有,但是返回类型必须要。

    Func<string,string> func = (string str) => { return str; };
if(func != null)
Console.WriteLine(func("hahaha"));

二、委托的应用

  委托的声明和使用其实不难,但是很大的一个困扰就是不知道什么时候使用,园中有很多委托的文章我看了很多,大家都举了很多的例子,比如烧开水啥的,但是我觉得还是用实际的例子来说明比较好。可能很多人在工作了几年后都没有用过委托。所以,实践出真知。只有当真正用到的时候才能明白其中的含义。

  这里举在窗体程序中的跨窗体调用方法的例子。现在有两个窗体Form1和Form2,分别由一个文本框和一个按钮。现在通过Form1中的按钮打开Form2窗体,然后通过Form2窗体中的按钮点击更新Form1中文本框的内容。

  Form1窗体的代码如下:

    private void OpenBtn_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.action = this.ModifyName;
form2.Show();
}
private void ModifyName(string name)
{
NameTxt.Text = name;
}

  Form2窗体的代码如下:

    public Action<string> action;
private void ModifyBtn_Click(object sender, EventArgs e)
{
ConfirmModify(action);
}
private void ConfirmModify(Action<string> action)
{
//省略数据库修改等操作.......
if (action != null)
  action(ModifyTxt.Text);
}

  代码非常简单,Form1和Form2中的方法都是私有的,只通过Form2中的委托对象来执行Form1中的私有方法。虽然还有别的方法可以实现这个功能,但是我觉得这个方案是比较好的。

三、总结

  有问题可以留言讨论,希望可以给大家带来帮助,共勉!

C#的委托Delegate的更多相关文章

  1. C#中的委托(Delegate)和事件(Event)

    原文地址:C#中的委托(Delegate)和事件(Event) 作者:jiyuan51 把C#中的委托(Delegate)和事件(Event)放到现在讲是有目的的:给下次写的设计模式--观察者(Obs ...

  2. (转)C#中的委托(Delegate)和事件(Event)

    转自:http://blog.chinaunix.net/uid-576762-id-2733751.html   把C#中的委托(Delegate)和事件(Event)放到现在讲是有目的的:给下次写 ...

  3. C#的委托(delegate、Action、Func、predicate)

    委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.事件是一种特殊的委托. 1.委托的声明 delegate我们常用到的一种声明 delegate至少0个参数,至多32个参 ...

  4. C#中的委托 Delegate(委托 也叫代表,代表一类方法)

    1. 委托类似与 C或C++中的函数指针,但委托是 面向对象的,并且是类型安全的 详情可查看官方文档:https://msdn.microsoft.com/en-us/library/ms173172 ...

  5. 关于C#的委托(delegate)的自我理解

    首先描述一个事情,一个老师饿了,他要去买东西填饱肚子,然后他发现他的学生“小李”在玩,没学习,于是就委托“小李”去帮他买吃的. 根据这件事我们来分析: 首先得有个老师(老师饿了是他的方法,老师买东西也 ...

  6. C#的委托 Action<>和Func<>

    其实他们两个都是委托[代理]的简写形式. 一.[action<>]指定那些只有输入参数,没有返回值的委托 Delegate的代码: [csharp]  public delegate vo ...

  7. Java与.net的区别delegate和event

    There is no delegate concept in Java The right-side C# program may be mimiced with reflection techno ...

  8. Objective-C Delegate

    ios设计模式中的委托 Delegate 官方文档解释如下: Delegation is a simple and powerful pattern in which one object in a ...

  9. Delegate,Action,Func,Predicate的使用与区别

    C#4.0推出后,类似Linq,Lamda表达式等许多新的程序写法层次不穷.与之相关的Delegate,Action,Func,Predicate的使用和区别也常常让大家迷惑,此处就结合实际的应用,对 ...

随机推荐

  1. March 11 2017 Week 10 Saturday

    Wisdom outweighs any wealth. 智慧比财富更有价值. Wisdom can create wealth if used in proper ways, it can help ...

  2. IIS环境搭建

    IIS环境搭建 IIS环境搭建首先是建立在一个干净的.无毒的系统上,再进行相应操作.本文用到的是windows 2003的镜像文件,有条件的用户也可以使用windows的系统安装光盘. 下面进入操作步 ...

  3. Android进阶笔记13:ListView篇之ListView刷新显示(全局 和 局部)

    一.ListView内容变化后,动态刷新的步骤(全局刷新): (1)更新适配器Adapter数据源:(不要使用匿名内部类) (2)调用适配器Adapter的刷新方法notifyDataSetChang ...

  4. Android(java)学习笔记45:深入分析Java ClassLoader原理

    1. 前言: Android中的动态加载机制能更好的优化我们的应用,同时实现动态的更新,这就便于我们管理我们的应用,通过插件化来减轻我们的内存以及CPU消耗,在不发布新版本的情况下能更新某些模块. 当 ...

  5. [USACO15OPEN]haybales Trappe…

    嘟嘟嘟 刚开始我以为如果这头牛撞开一个干草堆的话,获得的冲刺距离只有新增的部分,但实际上是加上原来的部分的. 暴力很好写,区间排完序后一次判断每一个区间是否能逃脱,复杂度O(n2). 优化想起来也不难 ...

  6. [19/03/20-星期三] 常用类_Enum(枚举)类

    一.概念(JDK 1.5之后才有的类) 所有的枚举(英语:enumeration) 类型隐性地继承自 java.lang.Enum.枚举实质上还是类,而每个被枚举的成员实质就是一个枚举类型的实例,他们 ...

  7. 2018.10.2 Eclipse中如何测地修改一个we项目步骤

    找到项目的web.xml文件 大概的路径如下: 修改xml文件中的display-name 节点的值 下一步就是切换工作目录 显示的效果 打开最后一个文件修改 接下来找到这个文件 是部署的时候用的 运 ...

  8. 【luogu P3369 普通平衡树(Treap/SBT)】 模板 Splay

    题目链接:https://www.luogu.org/problemnew/show/P3369 #include <cstdio> #include <algorithm> ...

  9. ipython notebook开通远程

    之前只是会用,别人告诉我命令和大概怎么设置的,今天自己搭建才发现一知半解搞不定啊. 目的:远程通过ipython notebook调用服务器. 服务器是ubuntu16.04 本地机器win7 配置方 ...

  10. LeetCode2.两数相加 JavaScript

    给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例: 输入:(2 -& ...