博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#委托详解(3):委托的实现方式大全(续)
阅读量:5308 次
发布时间:2019-06-14

本文共 3618 字,大约阅读时间需要 12 分钟。

接上篇(),本篇继续介绍委托的实现方式。

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

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

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

Func 
operations = MathOperations.MultiplyByTwo;

  等价于:

delegate double Operations(double x);    Operations operations = MathOperations.MultiplyByTwo;
即省略了对于委托类的定义。
  下面这个例子使用泛型委托实现了一个普通的冒泡排序算法,来看看跟普通的冒泡排序有什么不一样的:
  class BubbleSorter    {        static public void Sort
(IList
sortArray, Func
comparison) { bool swapped = true; while (swapped) { swapped = false; for (int i = 0; i < sortArray.Count - 1; i++) { if (comparison(sortArray[i+1], sortArray[i])) { T temp = sortArray[i]; sortArray[i] = sortArray[i + 1]; sortArray[i + 1] = 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", 20),                new Student("lisi", 12),                new Student("wangwu", 25),                new Student("zhaoliu", 10),            };            BubbleSorter.Sort(students, Student.CompareAge); //传入对象数组,和一个方法地址            foreach (var student in students)            {                Console.WriteLine(student);            }        }    }

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

 

5、匿名方法

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

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

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

6、Lambda表达式

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

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

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

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

  

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

 

转载于:https://www.cnblogs.com/Legolas/p/thorough-of-Delegate-3.html

你可能感兴趣的文章
linux中系统管理指令
查看>>
JS常用各种正则表达式
查看>>
Java 定时任务
查看>>
二分查找的平均查找长度详解【转】
查看>>
读阿里巴巴Java开发手册v1.2.0之编程规约有感【架构篇】
查看>>
基于page的简单页面推送技术
查看>>
js 日期格式化函数(可自定义)
查看>>
git报错:failed to push some refs to 'git@github.com:JiangXiaoLiang1988/CustomerHandl
查看>>
Eureka高可用,节点均出现在unavailable-replicas下
查看>>
day 21 - 1 包,异常处理
查看>>
机器学习等知识--- map/reduce, python 读json数据。。。
查看>>
字符串编码
查看>>
预编译语句(Prepared Statements)介绍,以MySQL为例
查看>>
Noip2011提高组总结
查看>>
HDU 4416 Good Article Good sentence(后缀自动机)
查看>>
Java异常之try,catch,finally,throw,throws
查看>>
spring的配置文件详解
查看>>
Spring框架第一篇之Spring的第一个程序
查看>>
操作文件
查看>>
.net core 12
查看>>