接上篇(C#委托详解(2):实现方式大全),本篇继续介绍委托的实现方式。

4、Action<T>和Func<T>委托

  使用委托时,除了为每个参数和返回类型定义一个新委托类型之外,还可以使用.NET Framework提供的泛型委托Action<T>和Func<T>,它们提供了从无参一直到最多16个参数的重载,如果方法需要获取16个以上的参数,就必须定义自己的委托类型,但这种情况应该是及其罕见的。其中Action<T>类可以调用没有返回值的方法,Func<T>允许调用带返回类型的方法。

  所以对于上一代码例子中的委托可以使用Func<double T, out Tresult>这样实现:

    Func <double, double> operations = MathOperations.MultiplyByTwo;

  等价于:

    delegate double Operations(double x);
Operations operations = MathOperations.MultiplyByTwo;
    即省略了对于委托类的定义。
  下面这个例子使用泛型委托实现了一个普通的冒泡排序算法,来看看跟普通的冒泡排序有什么不一样的:
  class BubbleSorter
{
static public void Sort<T>(IList<T> sortArray, Func<T, T, bool> comparison)
{
bool swapped = true;
while (swapped)
{
swapped = false;
for (int i = ; i < sortArray.Count - ; i++)
{
if (comparison(sortArray[i+], sortArray[i]))
{
T temp = sortArray[i];
sortArray[i] = sortArray[i + ];
sortArray[i + ] = temp;
swapped = true;
}
}
}
}
}

可以看到,代码实现没有什么不同,不同的是方法签名,第一个参数类型是IList<T>,它可以支持传入各种集合数据,第二个传入参数为一个委托对象,代表的是要排序的对象T的一个方法,这个方法会对两个对象T的大小进行比较,返回一个boolean类型的值,具体使用方法可以查看下面这段代码。

    class Student //需要排序的对象类型
{
public Student(string name, int salary)
{
this.Name = name;
this.Age = salary;
} public string Name { get; private set; }
public int Age { get; private set; } public override string ToString()
{
return string.Format("{0}, {1:C}", Name, Age);
} public static bool CompareAge(Student e1, Student e2)
{
return e1.Age < e2.Age;
}
} class Program
{
static void Main()
{
Student[] students =
{
new Student("zhangsan", ),
new Student("lisi", ),
new Student("wangwu", ),
new Student("zhaoliu", ),
}; BubbleSorter.Sort(students, Student.CompareAge); //传入对象数组,和一个方法地址
foreach (var student in students)
{
Console.WriteLine(student);
}
}
}

  上述代码中展示了委托的精髓,即将方法作为参数传递给其他方法,以增加代码的灵活性。(不清楚的童鞋一定仔细体会这种用法。)

5、匿名方法

  使用匿名方法定义委托与前面的定义没有什么区别,只是在实例化委托时,有一点区别。

    class Program
{
static void Main()
{
double width = ; Func<double, double> square = delegate(double length) //这里的square是委托类型的实例
{
length *= width;
return length;
};
Console.WriteLine(square());
}
}

  匿名方法的优点是减少了要编写的代码,不必定义仅由委托使用的方法。但如果需要用匿名方法多系编写同一个功能时就不建议使用匿名方法了。

6、Lambda表达式

  C#3.0开始支持Lambda表达式,可以使用其代替匿名方法。使用方法可以参考下面的例子:

            //1、不获取任何参数
Func<string> f = () => "lining";
//2、一个参数(可以显示指定类型也可以使用类型推断)
Func<int, string> f1 = (int n) => n.ToString();
Func<int, string> f2 = (n) => n.ToString();
Func<int, string> f3 = n => n.ToString();
//3、一个或多个参数
Func<int, int, string> f4 = (int n1, int n2) => (n1 + n2).ToString();
Func<int, int, string> f5 = (n1,n2) => (n1+n2).ToString();

  Lambda省去了书写方法,命名方法及传递方法的过程,可以减少代码量,提高编程效率。但其并没有对代码的执行效率带来优势。

  另外建议不要滥用lambda表达式,其对于调试和单步执行会带来一定的挑战。对于三行以上的代码推荐自己手动写一个方法,这样无论对于代码的可读性还是可服用性都是有益的。

  

本篇结束,对于委托的实现方式就先介绍这些,下一篇将介绍委托的Invoke,BeginInvoke和EndInvoke方法。

C#委托详解(3):委托的实现方式大全(续)的更多相关文章

  1. C#委托详解(2):实现方式大全

    本系列文章将详细探讨C#中的委托,列举其主要的实现方式,并分析其在设计层面和编码层面带来的好处,最后会讨论其安全性和执行效率等. 接上篇(C#委托详解(1):什么是委托)介绍完什么是委托之后,来看看C ...

  2. C#事件与委托详解

    from https://www.cnblogs.com/sjqq/p/6917497.html C#事件与委托详解[精华 多看看] Delegatedelegate是C#中的一种类型,它实际上是一个 ...

  3. 详解C#泛型(二) 获取C#中方法的执行时间及其代码注入 详解C#泛型(一) 详解C#委托和事件(二) 详解C#特性和反射(四) 记一次.net core调用SOAP接口遇到的问题 C# WebRequest.Create 锚点“#”字符问题 根据内容来产生一个二维码

    详解C#泛型(二)   一.自定义泛型方法(Generic Method),将类型参数用作参数列表或返回值的类型: void MyFunc<T>() //声明具有一个类型参数的泛型方法 { ...

  4. LVS原理详解(3种工作方式8种调度算法)--老男孩

    一.LVS原理详解(4种工作方式8种调度算法) 集群简介 集群就是一组独立的计算机,协同工作,对外提供服务.对客户端来说像是一台服务器提供服务. LVS在企业架构中的位置: 以上的架构只是众多企业里面 ...

  5. c# 委托详解

    1.委托声明 2.委托入门实例 namespace ConsoleApplication1 { public delegate void methodDelegate(string str); cla ...

  6. C#事件与委托详解【精华 多看看】

    Delegate delegate是C#中的一种类型,它实际上是一个能够持有对某个方法的引用的类.与其它的类不同,delegate类能够拥有一个签名(signature),并且它"只能持有与 ...

  7. 【C#】详解C#委托

    目录结构: contents structure [+] 委托语法 泛型委托 委托链 lambda表达式 揭秘委托 类库中的委托 委托和反射 1.委托语法 本文会详细阐述委托的使用,以及实现,想必读者 ...

  8. 详解C#委托和事件(一)

    委托(Delegate)是安全封装方法的类型,类似于C和C++中的函数指针,与函数指针不同的是,委托是面向对象的.类型安全的和可靠的: 一.委托类型是CTS中五种基础类型之一,是一种引用类型,表示对具 ...

  9. c#之委托详解(Delegate)

    一.委托的概念 在我们学习委托之前,我们来了解下,什么是委托呢? 官方概念:委托是一种安全地封装方法的类型,它与 C 和 C++ 中的函数指针类似.与 C 中的函数指针不同,委托是面向对象的.类型安全 ...

随机推荐

  1. CentOS学习笔记--vi程序编辑器

    vi程序编辑器 Linux里经常需要修改一些配置文件,这时就需要一个编辑器,几乎所有的Linux版本都提供了vi这个编辑器. 文件内容查阅cat命令 如果我们要查阅一个文件的内容时,该如何是好呢?这里 ...

  2. PHP高级笔记汇总

    一.PHP日期 PHP的date()函数用于格式化时间或日期.PHP Date()函数可把时间戳格式化为可读性更好的日期和时间.语法:date(format,timestamp)format:必需.规 ...

  3. iOS网络通讯——监测网络状态:Reachability(可达性)

    1.iOS平台是按照一直有网络连接的思路来设计的,开发者利用这一特点创造了很多优秀的第三方应用.大多数的iOS应用都需要联网,甚至有些应用严重依赖网络,没有网络就无法正常工作. 2.在你的应用尝试通过 ...

  4. SQL Server :DBLINK创建及使用

    Exec sp_droplinkedsrvlogin bvtwfld12,Null --若存在先刪除Exec sp_dropserver bvtwfld12EXEC sp_addlinkedserve ...

  5. bootstrap知识小点

    年底没什么项目做了,整理下最近做的网站使用到的bootstrap知识 一.导入bootstrap样式和脚本 <link href="css/bootstrap.min.css" ...

  6. APK反编译之一

    初步接触APK反编译.刚刚使用android-apktool软件反编译了一下QQ.apk,目的只是想看看QQ这个应用软件是内部是如何设计的,希望可以在某些方面借鉴一下.下面就如何反编译做一个简单的记录 ...

  7. Mayan游戏 (codevs 1136)题解

    [问题描述] Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个7行5列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定的 ...

  8. 编写测试类,了解ArrayList的方法

    这篇文章主要介绍了C#中动态数组用法,实例分析了C#中ArrayList实现动态数组的技巧,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了C#中动态数组用法.分享给大家供大家参考.具体分析如下 ...

  9. How to create Lookup Worker Filtered by Legal Entity[AX2012]

    1. Add a new method in hcmWorker table, and add this script : public static client void lookupWorker ...

  10. 利用JQ实现的,高仿 彩虹岛官网导航栏(学习HTML过程中的小记录)

    利用JQ实现的,高仿 彩虹岛官网导航栏(学习HTML过程中的小记录)   作者:王可利(Star·星星) 总结: 今天学习的jQ类库的使用,代码重复的比较多需要完善.严格区分大小写,在 $(" ...