C#委托的介绍(delegate、Action、Func、predicate)

from:http://www.cnblogs.com/akwwl/p/3232679.html

委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递。事件是一种特殊的委托。

1.委托的声明

(1). delegate

delegate我们常用到的一种声明

Delegate至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型。

例:public delegate int MethodtDelegate(int x, int y);表示有两个参数,并返回int型。

(2). Action

Action是无返回值的泛型委托。

Action 表示无参,无返回值的委托

Action<int,string> 表示有传入参数int,string无返回值的委托

Action<int,string,bool> 表示有传入参数int,string,bool无返回值的委托

Action<int,int,int,int> 表示有传入4个int型参数,无返回值的委托

Action至少0个参数,至多16个参数,无返回值。

例:

        public void Test<T>(Action<T> action,T p)
{
action(p);
}

(3). Func

Func是有返回值的泛型委托

Func<int> 表示无参,返回值为int的委托

Func<object,string,int> 表示传入参数为object, string 返回值为int的委托

Func<object,string,int> 表示传入参数为object, string 返回值为int的委托

Func<T1,T2,,T3,int> 表示传入参数为T1,T2,,T3(泛型)返回值为int的委托

Func至少0个参数,至多16个参数,根据返回值泛型返回。必须有返回值,不可void

例:

        public int Test<T1,T2>(Func<T1,T2,int>func,T1 a,T2 b)
{
return func(a, b);
}

(4) .predicate

predicate 是返回bool型的泛型委托

predicate<int> 表示传入参数为int 返回bool的委托

Predicate有且只有一个参数,返回值固定为bool

例:public delegate bool Predicate<T> (T obj)

2.委托的使用

(1).Delegate的使用

        public delegate int MethodDelegate(int x, int y);
private static MethodDelegate method;
static void Main(string[] args)
{
method = new MethodDelegate(Add);
Console.WriteLine(method(10,20));
Console.ReadKey();
} private static int Add(int x, int y)
{
return x + y;
}

(2).Action的使用

 static void Main(string[] args)
{
Test<string>(Action,"Hello World!");
Test<int>(Action, 1000);
Test<string>(p => { Console.WriteLine("{0}", p); }, "Hello World");//使用Lambda表达式定义委托
Console.ReadKey();
}
public static void Test<T>(Action<T> action, T p)
{
action(p);
}
private static void Action(string s)
{
Console.WriteLine(s);
}
private static void Action(int s)
{
Console.WriteLine(s);
}

可以使用 Action<T1, T2, T3, T4> 委托以参数形式传递方法,而不用显式声明自定义的委托。 封装的方法必须与此委托定义的方法签名相对应。 也就是说,封装的方法必须具有四个均通过值传递给它的参数,并且不能返回值。 (在 C# 中,该方法必须返回 void)通常,这种方法用于执行某个操作。

(3).Func的使用

        static void Main(string[] args)
{
Console.WriteLine(Test<int,int>(Fun,100,200));
Console.ReadKey();
}
public static int Test<T1, T2>(Func<T1, T2, int> func, T1 a, T2 b)
{
return func(a, b);
}
private static int Fun(int a, int b)
{
return a + b;
}

(4). predicate的使用

泛型委托:表示定义一组条件并确定指定对象是否符合这些条件的方法。此委托由 Array 和 List 类的几种方法使用,用于在集合中搜索元素。

        static void Main(string[] args)
{
Point[] points = { new Point(100, 200),
new Point(150, 250), new Point(250, 375),
new Point(275, 395), new Point(295, 450) };
Point first = Array.Find(points, ProductGT10);
Console.WriteLine("Found: X = {0}, Y = {1}", first.X, first.Y);
Console.ReadKey();
}
private static bool ProductGT10(Point p)
{
if (p.X * p.Y > 100000)
{
return true;
}
else
{
return false;
}
}

使用带有 Array.Find 方法的 Predicate 委托搜索 Point 结构的数组。如果 X 和 Y 字段的乘积大于 100,000,此委托表示的方法 ProductGT10 将返回 true。Find 方法为数组的每个元素调用此委托,在符合测试条件的第一个点处停止。

3.委托的清空

因为可以有多重委托,即

  1.委托的调用其实是一个调用列表,可以同时调用多个不同的方法
  2.第1个委托加上第2个委托赋予第3个委托,相当于把两个方法按顺序一排,先调用第一个方法,再调用第二个方法
  3.当一个委托列表为空的时候,对它进行调用会报错

(1).在类中申明清空委托方法,依次循环去除委托引用。

方法如下:

      public MethodDelegate OnDelegate;
public void ClearDelegate()
{
while (this.OnDelegate != null)
{
this.OnDelegate -= this.OnDelegate;
}
}

(2).如果在类中没有申明清空委托的方法,我们可以利用GetInvocationList查询出委托引用,然后进行去除。

方法如下:

        public MethodDelegate OnDelegate; 
     static void Main(string[] args)
{
Program test = new Program(); if (test.OnDelegate != null)
{
System.Delegate[] dels = test.OnDelegate.GetInvocationList();
for (int i = 0; i < dels.Length; i++)
{
test.OnDelegate -= dels[i] as MethodDelegate;
}
}
}

4.委托的特点

委托类似于 C++ 函数指针,但它们是类型安全的。 
委托允许将方法作为参数进行传递。 
委托可用于定义回调方法。 
委托可以链接在一起;例如,可以对一个事件调用多个方法。 
方法不必与委托签名完全匹配。

5.总结:

Delegate至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型

Func可以接受0个至16个传入参数,必须具有返回值

Action可以接受0个至16个传入参数,无返回值

Predicate只能接受一个传入参数,返回值为bool类型

C#委托(转载)的更多相关文章

  1. C#动态对象(dynamic)示例(实现方法和属性的动态)

    C#的动态对象的属性实现比较简单,如果要实现动态语言那种动态方法就比较困难,因为对于dynamic对象,扩展方法,匿名方法都是不能用直接的,这里还是利用对象和委托来模拟这种动态方法的实现,看起来有点J ...

  2. 转载 C#匿名函数 委托和Lambda表达式

    转载原出处: http://blog.csdn.net/honantic/article/details/46331875 匿名函数 匿名函数(Anonymous Function)是表示“内联”方法 ...

  3. 转载:C#中事件和委托的编译代码

    接上文转载:C#中事件的由来,这时候,我们注释掉编译错误的行,然后重新进行编译,再借助Reflactor来对 event的声明语句做一探究,看看为什么会发生这样的错误: public event Gr ...

  4. 转载: jQuery事件委托( bind() \ live() \ delegate()) [委托 和 绑定的故事]

    转载:http://blog.csdn.net/zc2087/article/details/7287429 随着DOM结构的复杂化和Ajax等动态脚本技术的运用,事件委托自然浮出了水面.jQuery ...

  5. Delegate,Action,Func,匿名方法,匿名委托,事件 (转载)

    Delegate,Action,Func,匿名方法,匿名委托,事件 (转载) 一.委托Delegate 一般的方法(Method)中,我们的参数总是string,int,DateTime...这些基本 ...

  6. [转载]C#深入分析委托与事件

    原文出处: 作者:风尘浪子 原文链接:http://www.cnblogs.com/leslies2/archive/2012/03/22/2389318.html 同类链接:http://www.c ...

  7. [转载]C#委托和事件(Delegate、Event、EventHandler、EventArgs)

    原文链接:http://blog.csdn.net/zwj7612356/article/details/8272520 14.1.委托 当要把方法作为实参传送给其他方法的形参时,形参需要使用委托.委 ...

  8. C#委托的介绍(delegate、Action、Func、predicate) --转载

    来源:http://www.cnblogs.com/akwwl/p/3232679.html 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.事件是一种特殊的委托. 1 ...

  9. 《C#高级编程》之委托学习笔记 (转载)

    全文摘自 http://www.cnblogs.com/xun126/archive/2010/12/30/1921551.html 写得不错,特意备份!并改正其中的错误代码..     正文: 最近 ...

随机推荐

  1. [java] 为什么重写equals()必须要重写hashCode()

    本文版权归 远方的风lyh和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 在Java API文档中关于hashCode方法有以下几点规定(原文来自java深入解析一书) 1 在j ...

  2. SpringMVC跨域问题排查以及源码实现

    SpringMVC跨域问题排查以及源码实现 最近一次项目中,将SpringMVC版本从4.1.1升级到4.3.10,出现跨域失败的情况.关于同源策略和跨域解决方案,网上有很多资料. 项目采用的方式是通 ...

  3. Python 通过 SMTP 发送邮件

    Python版本:Python3.5.2 简介 SMTP是发送邮件的协议,Python 内置对 SMTP 的支持,可以发送纯文本邮件.HTML 邮件以及带附件的邮件. Python 对 SMTP 支持 ...

  4. 使用LayoutInflater添加一个布局引用

    LayoutInflater 与 xml 的<include/>的区别,至今没搞清楚,下面记录一下LayoutInflater引用一个布局并立即显示呈现的方法: private void ...

  5. 《C#并发编程经典实例》学习笔记—异步编程关键字 Async和Await

    C# 5.0 推出async和await,最早是.NET Framework 4.5引入,可以在Visual Studio 2012使用.在此之前的异步编程实现难度较高,async使异步编程的实现变得 ...

  6. C# 只开启一个程序,如果第二次打开则自动将第一个程序显示到桌面

    using System; using System.Collections.Generic; using System.Windows.Forms; using System.Runtime.Int ...

  7. .NET 单元测试的利剑——模拟框架Moq(简述篇)

    .NET 单元测试的利剑--模拟框架Moq 前言 这篇文章是翻译文,因为通过自己参与的项目,越发觉得单元测试的重要性,特别是当跟业务数据打交道的时候的,Moq就如雪中送炭,所以想学习这个框架,就从这篇 ...

  8. [PHP] 算法-顺时针打印矩阵的PHP实现

    1.行数和列数取出来row,col,圈数就是 (较小值-1)/2+1 2.外层循环控制圈数,内层四个for循环,i 3.第一个for循环,从左到右,j=i;j<col-i;j++;j<; ...

  9. Spring 与 SpringMVC (或许不完整)

    一.什么是Spring Spring是一个开源的控制反转和面向切面(AOP)的容器框架.它的主要目的是使现有技术更加易用,推荐编码最佳实现,从而简化企业的开发. 提:使用Spring的好处有以下几项: ...

  10. 用函数式编程对JavaScript进行断舍离

    译者按: 当从业20的JavaScript老司机学会函数式编程时,他扔掉了90%的特性,也不用面向对象了,最后发现了真爱啊!!! 原文: How I rediscovered my love for ...