第五节:委托的使用

编程入门 行业动态 更新时间:2024-10-23 20:26:32

<a href=https://www.elefans.com/category/jswz/34/1745372.html style=第五节:委托的使用"/>

第五节:委托的使用

​​​​​​一  委托解释

简单说它就是一个能把方法当参数传递的对象,而且还知道怎么调用这个方法,同时也是粒度更小的“接口”(约束了指向方法的签名)。

二 委托简单使用

一个委托类型定义了该类型的实例能调用的一类方法,这些方法含有同样的返回类型 和同样参数(类型和个数相同)。委托和接口一样,可以定义在类的外部。如下定义了一个委托类型 - Calculator:(计算机委托)

  delegate int Calculator (int x);   

 此委托适用于任何有着int返回类型和一个int类型参数的方法,如:

委托的使用public delegate int Calculator(int x);public static int  Double(int x){return x * 2;}

  2.1 委托调用:

  //委托调用,(同类型,同参数类的方法)就能通过委托调用定义的这些方法,不需要实例化//第一种写法Calculator c = new Calculator(Double);int result = c(2);//第二种写法Calculator c1 = Double;int result1 = c(2);

三 用委托实现插件式编程

    解释:我们可以利用“ 委托是一个能把方法作为参数传递的对象 ” 这一特点,来实现一种插件式编程。

    3.1 例如,我们有一个Utility类,这个类实现一个通用方法(Calculate),用来执行任何有一个整型参数和整型返回值的方法。这样说有点抽象,下面来看一个例子:

namespace MyDelegate
{//定义一个委托类,在传建一个 类型相同,参数类型相同的方法在使用委托public  class BaseDelegate{public delegate int Calculator(int x);public static int  Double(int x){return x * 2;}}//写一个公共的方法把委托当参数来使用,就可以实现所有int 类型的方法和int 类型的返回值都可以调用这个参数使用public  class Utility{public static void Calculate(int[] values, Calculator c){for (int i = 0; i < values.Length; i++) values[i] = c(values[i]);}}
}

3.2 公共方法委托调用

 //在这里也可以定义委托 class Program{static void Main(string[] args){int[] values = { 1, 2, 3, 4 };//这是调用了公共方法把委托当初 参数来调用// Double  就是使用了委托Utility.Calculate(values, Double);foreach (int i in values){Console.Write(i + " "); // 2 4 6 8      }Console.ReadKey();}}

四 多播委托

 多播委托解释:

所有的委托实例都有多播的功能。所谓多播,就像一群程序员在瞬聘网填好了求职意向后,某天有个公司发布了一个和这些程序员求职意向刚好相匹配的工作,然后这些求职者都被通知了 - “有一份好工作招人啦,你们可以直接申请去上班了!”。也就是说,一个委托实例不仅可以指向一个方法,还可以指向多个方法

例如:多播委托添加/移除案例如下

  委托的定义,和可以使用委托的方法public class MyDelegateTest{//先定义一个委托 一个无参返回类型,无参的委托方法public delegate void ProgressReporter();public static void GetMothe1(){Console.WriteLine("我是委托第一个");}public static void GetMothe2(){Console.WriteLine("我是委托第二个");}public static  void GetMothe3(){Console.WriteLine("我是委托第三个");}public static void GetMothe4(){Console.WriteLine("我是委托第四个");}public static void GetMothe5(){Console.WriteLine("我是委托第五个");}}

怎么调用委托进行新增移除委托?如下

          Console.WriteLine("**********  我在测试多播委托 添加 **************");ProgressReporter delegateTest =GetMothe1;delegateTest += GetMothe2;delegateTest += GetMothe3;delegateTest += GetMothe4;delegateTest += GetMothe5;//Invoke  作用是:调用委托方法,冲第一个到最后一个按顺序来执行delegateTest.Invoke();Console.WriteLine("********   我在测试多播委托 移除  **********");ProgressReporter delegateTest1 = GetMothe1;delegateTest1 -= GetMothe2;delegateTest1 -= GetMothe3;delegateTest1 -= GetMothe4;delegateTest1 -= GetMothe5;//Invoke  作用是:调用委托方法,冲第一个到最后一个按顺序来执行delegateTest.Invoke();

五 下面来探讨一下  静态方法和实例方法对于委托的区别

当一个类的实例的方法被赋给一个委托对象时,在上下文中不仅要维护这个方法,还要维护这个方法所在的实例。
System.Delegate 类的Target属性指向的就是这个实例

但对于静态方法,System.Delegate 类的Target属性是Null,所以将静态方法赋值给委托时性能更优

六 泛型委托

 解释:如果你知道泛型,那么就很容易理解泛型委托,说白了就是含有泛型参数的委托

C#  3.0 新语法在 using 后面加上 static  就不需要在创建类的实例化,可以直接使用该类的所有方法包括属性

using static MyDelegate.BaseDelegate;
using static MyDelegate.GenericDelegate;
using static MyDelegate.MyDelegateTest;
using static MyDelegate.Student;

创建泛型委托代码如下:

    /// <summary>/// 泛型委托/// </summary>public class GenericDelegate{/// <summary>/// 泛型委托,返回值 是 T 类型,参数也是 T 类型,/// 只要方法能匹配这个泛型委托方法就可以进行调用/// </summary>/// <param name="a"></param>/// <returns></returns>public delegate T GenericDelegateMothe<T>(T t);//泛型方法给泛型委托调用public static T GenericDelegateInt<T>(T iPaer){Console.WriteLine($"我是 {iPaer.GetType().Name}类型 的泛型委托实现方法");return iPaer;}//普通方法给 泛型委托调用public static string  GenericDelegateString(string  sPaer){Console.WriteLine($"我是 {sPaer.GetType().Name}类型 的泛型委托实现方法");return sPaer;}}

泛型委托调用

       Console.WriteLine("********* 泛型委托  泛型方法的调用  ****************   ");GenericDelegateMothe<int> delegateMothe = GenericDelegateInt<int>;delegateMothe.Invoke(7);Console.WriteLine("******** 泛型委托 普通方法的调用  ******************   ");GenericDelegateMothe<string> mothe = GenericDelegateString;mothe.Invoke("你好");总结: 如果使用了泛型委托,应该要使用泛型方法来实现这个泛型委托,而不是用普通方法实现这个泛型委托,
因为 泛型方法可以适用于所有类的方法调用,而不是使用普通方法来用泛型委托, 这样就没意义了,就把泛型委托的扩展性给限制了

六  Func 和 Action 委托

 有了泛型委托,就有了一个能适用于任何返回类型和任意参数(类型和合理的个数)的通用委托,Func 和 Action。

如下所示(下面的 in 表示参数,out  表示返回结果):

delegate TResult Func <out TResult> ();
delegate TResult Func <in T, out TResult> (T arg);
delegate TResult Func <in T1, in T2, out TResult> (T1 arg1, T2 arg2); ... 一直到 T16 
-----------------------------------------
delegate void Action ();
delegate void Action <in T> (T arg);
delegate void Action <in T1, in T2> (T1 arg1, T2 arg2); ... 一直到 T16

使用 Func <out TResult> () 和  Action<in T>()  的调用

           {//使用Fun 来调用 有参数,有返回值的的委托泛型方法(这是普通方法)Func<string, string> func = GenericDelegateString;func.Invoke("我使用 Fun 带返回值的委托方法");//使用泛型委托调用Func<int,int> f = GenericDelegateInt<int>;f.Invoke(98);//是用 Action   来调用 无返回值 有参数的 委托Action<string> action = Show;action.Invoke("刘建峰");}

总结:这里这俩个委托之后,我们就可有不用特意创建委托了带参数,带返回值的就是用 Func <out TResult> (),

          带参数,不带返回值的就是用 Action<in T>() 这个委托,

 为什么有这来个委托呢?

  因为为了统一,不会被搞乱,如果委托定义多了就不知道那个创建的委托可以调用那个方法了,所以微软官方就封装了俩个委托供大家使用

7 委托的兼容

   7.1. 委托的类型兼容

delegate void D1();
delegate void D2();D1 d1 = Method1;
D2 d2 = d1;
下面是被允许的:D2 d2 = newD2 (d1);
对于具体相同的目标方法的委托是被视为相等的:delegate void D();D d1 = Method1;
D d2 = Method1;
Console.WriteLine (d1 == d2); // True
同理,对于多播委托,如果含有相同的方法和相同的顺序,也被视为相等。

    7.2 参数类型兼容、

在OOP中,任何使用父类的地方均可以用子类代替,这个OOP思想对委托的参数同样有效。如:
delegate void StringAction(string s);
class Program {     static void Main() {         StringAction sa = new StringAction(ActOnObject);     sa("hello");   
}    static void ActOnObject(object o) {      Console.WriteLine(o); // hello     } 
}

7.3. 返回值类型兼容

delegate object ObjectRetriever();
class Program {    static void Main() {     ObjectRetriever o = new ObjectRetriever(RetriveString);   object result = o();        Console.WriteLine(result); // hello    
}     static string RetriveString(){ return "hello"; } 
}

 

 

 

 

 

 

 

 

 

 

 

更多推荐

第五节:委托的使用

本文发布于:2024-03-11 20:05:49,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1729798.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:第五节

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!