c# 最初的时候 只有 delegate,之后的版本封装了Action<T> 、Func<T>、EventHandler<T>

关于Action<T> 

实际上Action<T>  等同于旧版的

 public delegate void Action();
public delegate void Action<T1>(T1 arg1);
public delegate void Action<T1, T2>(T1 arg1, T2 arg2);
public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
public delegate void Action<T1, T2, T3, T4, T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);

新版写法一:

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
//同步执行
Action Action = new Action(writeLine);
Action.Invoke();
//异步执行
Action ActionAsy = new Action(writeLine2);
ActionAsy.BeginInvoke(resual=>Console.WriteLine("异步执行结束"), null);
Console.Read();
}
private static void writeLine()
{
Console.WriteLine("Action同步执行委托");
}
private static void writeLine2()
{
Console.WriteLine("Action异步执行委托");
}

新版写法2(lambda表达式)

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
//同步执行 用Lambda表达式代替writeLine
Action Action = new Action(()=>Console.WriteLine("Action同步执行委托"));
Action.Invoke();
//异步执行 用Lambda表达式代替writeLine2
Action ActionAsy = new Action(()=>Console.WriteLine("Action异步执行委托"));
ActionAsy.BeginInvoke(resual=>Console.WriteLine("异步执行结束"), null);
Console.Read();
}

新版写法3(带参数的)

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
//同步执行 传入一个参数
Action<string> Action = new Action<string>((a)=>Console.WriteLine(string.Format("Action同步执行委托,传入参数:{0}",a)));
Action.Invoke("小李");
//异步执行 传入两个参数
Action<string,int> ActionAsy = new Action<string,int>((a,b)=>Console.WriteLine("Action异步执行委托,传入参数:{0},{1}",a,b));
ActionAsy.BeginInvoke("小李",,resual=>Console.WriteLine("异步执行结束"), null);
Console.Read();
}

在上面代码中,同步定义的string类型,必须保证传入的参数a也是string。虽然并没有对a进行类型定义,但是系统默认就是事先泛型中定义的类型。类似的,异步委托也是一样。不然会报错。


关于Func<T>

实际上 Func<T>等同于旧版的

 public delegate TResult Func<TResult>();
public delegate TResult Func<T1, TResult>(T1 arg1);
public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
public delegate TResult Func<T1, T2, T3, T4, T5, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);

Func<T>委托的定义是相对于Action<T>来说。Action<T>是没有返回值得方法委托,Func<T>是有返回值的委托。返回值的类型,由泛型中定义的类型进行约束。例如:

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
//异步执行
Func<string> FuncAsy = new Func<string>(() =>
{
people tPeo = new people("异步小李", );
return tPeo.ToString();
}
);
FuncAsy.BeginInvoke(resual =>
{
//异步执行,从回调函数中获取返回结果
Console.WriteLine(FuncAsy.EndInvoke(resual));
Console.WriteLine("异步执行结束");
}, null);
//同步执行
Func<string> Func = new Func<string>(() =>
{
people tPeo = new people("同步小李", );
return tPeo.ToString();
}
);
//同步执行,获取返回结果
Console.WriteLine(Func.Invoke());
Console.Read();
}
public class people
{
public string Name { get; set; }
public int Age { get; set; }
public people(string pName, int pAge)
{
this.Name = pName;
this.Age = pAge;
}
public override string ToString()
{
return string.Format("名称叫{0},年龄{1}", this.Name, this.Age);
}
}

多参数新版写法:

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
//异步执行 传入一个people类型的参数,返回一个sting类型的结果
Func<people, string> FuncAsy = new Func<people, string>((pPeople) =>
{
return pPeople.Name;
}
);
FuncAsy.BeginInvoke(new people("异步小李", ), resual =>
{
//异步执行,从回调函数中获取返回结果
Console.WriteLine(FuncAsy.EndInvoke(resual));
Console.WriteLine("异步执行结束");
}, null);
//同步执行 传入一个string,int类型的参数,返回一个people类型的结果
Func<string, int, people> Func = new Func<string, int, people>((pName,pAge) =>
{
people tPeo = new people(pName, pAge);
return tPeo;
}
);
//同步执行,返回结果
Console.WriteLine(Func.Invoke("同步小李",).ToString());
Console.Read();
}

关于EventHandler<T>

实际上 EventHandler<T> 等同于旧版的

public delegate void CustomEventHandler(object sender, CustomEventArgs a);
public event CustomEventHandler RaiseCustomEvent;

新版写法:

public event EventHandler<CustomEventArgs> RaiseCustomEvent;

1:EventHandler实际上就是一个特殊的委托,它是由.NET预定义好的一个委托,它的形式是固定的。
2:使用EventHandler时,处理函数的返回值必须是Void类型,而使用Deleagate则没有这个限制。
3:Delegate相当于一个函数的指针,用于绑定的函数返回值和参数列表要符合Delegate声明时的要求。

参考资料:http://www.cnblogs.com/cglNet/p/3395954.html

关于Action<T> 、Func<T>、EventHandler<T>、event、delegate的更多相关文章

  1. C#扫盲篇(三):Action和Func委托--实话实说

    一.基础定义 老王想找老张的老婆出去耍,但是一看,老张还在厨房煮饭.于是老王就对老张隔壁的淑芬说:"等下老张吃完饭出去喝茶,你就把前门晒的苞谷收了,老张从左门出,你就收右边的苞谷,我就知道从 ...

  2. .NET中的Action及Func泛型委托

    委托,在C#编程中占有极其重要的地位,委托可以将函数封装到委托对象中,并且多个委托可以合并为一个委托,委托对象则可以像普通对象一样被存储.传递,之后在任何时刻进行调用,因此,C#中函数回调机制的实现基 ...

  3. 使用.NET中的Action及Func泛型委托

          委托,在C#编程中占有极其重要的地位,委托可以将函数封装到委托对象中,并且多个委托可以合并为一个委托,委托对象则可以像普通对象一样被存储.传递,之后在任何时刻进行调用,因此,C#中函数回调 ...

  4. Delegate、Predicate、Action和Func

    写在前面 Delegate Predicate Action Func 逆变和协变 先说下什么是委托(Delegate),委托在C#中是一种类型,和Class是一个级别,但是我们经常把它看做是一个方法 ...

  5. VS2012 Unit Test(Void, Action, Func) —— 对无返回值、使用Action或Func作为参数、多重载的方法进行单元测试

    [提示] 1. 阅读文本前希望您具备如下知识:了解单元测试,了解Dynamic,熟悉泛型(协变与逆变)和Lambda,熟悉.NET Framework提供的 Action与Func委托.2.如果您对单 ...

  6. EXPLAINING WHAT ACTION AND FUNC ARE

    http://simpleprogrammer.com/2010/09/24/explaining-what-action-and-func-are/ Explaining What Action A ...

  7. C#系统委托之Action And Func

    Action Action<T> Func Func<T> Action:封装一个方法,该方法不具有参数并且不返回值 public delegate void Action() ...

  8. Action<>和Func<> 委托【代理】

    C#中的Action<>和Func<> 其实他们两个都是委托[代理]的简写形式. 一.[action<>]指定那些只有输入参数,没有返回值的委托 Delegate的 ...

  9. [C#] 委托之Action和Func区别

    一.说明 一般我们定义委托都是有如下两步: public delegate void MyDelegate(string name);//定义委托 public MyDelegate myDelega ...

  10. C#高级功能(三)Action、Func,Tuple

    Action和Func泛型委托实际上就是一个.NET Framework预定义的委托,3.5引入的特性.基本涵盖了所有常用的委托,所以一般不用用户重新声明. Action系列泛型委托,是没有返回参数的 ...

随机推荐

  1. selenium执行js报错

    selenium执行js报错 Traceback (most recent call last):    dr.execute_script(js)  File "C:\Python27\l ...

  2. typeof、offsetof、container_of的解释

    链表是内核最经典的数据结构之一,说到链表就不得不提及内核最经典(没有之一)的宏container_of. container_of似乎就是为链表而生的,它的主要作用是根据一个结构体变量中的一个域成员变 ...

  3. 关于java发起http请求

    我们到底能走多远系列(41) 扯淡: 好久没总结点东西了,技术上没什么总结,感觉做事空牢牢的.最近也比较疲惫. 分享些东西,造福全人类~ 主题: 1,java模拟发起一个http请求 使用HttpUR ...

  4. Linux磁盘文件的命名

    磁盘的常用接口有两种:IDE和SATA接口,目前主流的是SATA接口. IDE接口由IDE扁平电缆线连接,一个电缆可连接两个IDE接口,通常主机又都会提供两个IDE接口,因此最多可以接到四个IDE设备 ...

  5. 215. Kth Largest Element in an Array

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  6. 2015GitWebRTC编译实录9

    2015.07.20 neteq 编译通过注意不要引用tools目录里的内容 [1347/1600 ] CXX obj /webrtc/modules/audio_coding/neteq/neteq ...

  7. HDU 4686 矩阵快速幂 Arc of Dream

    由式子的性质发现都是线性的,考虑构造矩阵,先有式子,a[i] = ax * a[i-1] + ay; b[i] = bx*b[i-1] +by; a[i]*b[i] = ax*bx*a[i-1]*b[ ...

  8. PCL可视化显示 直接加载显示pcb文件

    简单可视化类,是指直接在程序中使用,而且不支持多线程. #include<iostream> #include<pcl\point_cloud.h> #include<p ...

  9. Codeforces Round #373 (Div. 1)

    Codeforces Round #373 (Div. 1) A. Efim and Strange Grade 题意 给一个长为\(n(n \le 2 \times 10^5)\)的小数,每次可以选 ...

  10. IOS中如果使用RGB实现背景色

    在开发的过程中.我们往往会碰到图片很多的情况.这时候我们的程序打包就会变得很大.一些纯色的图片可以用RGB来实现.这样可以减少内存的占用MAC本中有数码测色计这个功能.通过这个我们可以获得图片的RGB ...