【.NET Core】委托(Delegate)应用详解

news/2024/5/19 21:48:35 标签: .netcore, c#, 开发语言, asp.net, microsoft, wpf

【.NET Core】委托(Delegate)应用详解

文章目录

  • 【.NET Core】委托(Delegate)应用详解
    • 一、概述
    • 二、委托(Delegate)定义
    • 三、基础委托(Delegate) - 无返回值委托
    • 四、基础委托(Delegate) - 有返回值委托
    • 五、MulticastDelegate 多播委托
    • 六、匿名方法
    • 七、匿名委托之Action
    • 八、匿名委托之Func
    • 九、委托总结
    • 十、参考资料

一、概述

委托(Delegate)是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。委托(Delegate)类似于C或C++中函数指针。委托是将方法调用者和目标方法动态关联起来,委托是一个类,实质上是一个类,可以通过委托隐藏方法,虽然委托定义方法的参数及其返回值,但是它并不是和方法一个层级的。

委托(Delegate)可以将方法当作另一个方法的参数来进行传递,这种方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

二、委托(Delegate)定义

声明一个委托的语法如下:

c#">deletgate <return type> <delegate-name> <parameter list>
  • delegate 定义委托关键字
  • return type 返回类型 (与方法返回值相同)
  • delegate-name 委托的命名
  • parameter list 参数列表 (与方法入参相同)

声明委托步骤

  1. 声明一个delegate对象,它应当与要传统的方法具有相同的参数和返回值类型。
  2. 创建delegate对象,new Delegate传入参数
  3. 通过delegate调用方法,并返回值。

代码演示

c#">delegate int DegaAdd(int a,int b,int c);
public int add(int a,int b,int c){
    return a+b+c;
}
public static void Main(String[] args){
    DegaAdd degaAdd=new DegaAdd(add);
    int respVal =degaAdd(2,3,4);
    Console.WriteLine(respVal);
}

三、基础委托(Delegate) - 无返回值委托

c#">public class Program 
{
    public delegate void DelegateNoReturn(string param1, string param2);
    public static void NoReturn(string param1, string param2) 
    {
        Console.WriteLine(param1+" "+param2+".");
    }
    public static void Main(string[] args) 
    {
        DelegateNoReturn delegateNoReturn;
        delegateNoReturn = NoReturn;
        delegateNoReturn("Hello", "Delegate");

    }
}

四、基础委托(Delegate) - 有返回值委托

c#">public class Program 
{
    public delegate void DelegateNoReturn(string param1, string param2);
    public delegate string DelegateHaveReturn(string param1, string param2);
    public static void NoReturn(string param1, string param2) 
    {
        Console.WriteLine(param1+" "+param2+".");
    }
    public static string HaveReturn(string param1, string param2) {
      return ("有参数Delegate:"+param1 + " " + param2 + ".");
    }
    public static void Main(string[] args)
    {
        DelegateHaveReturn delegateHaveReturn;
        delegateHaveReturn = HaveReturn;
        string response = delegateHaveReturn("Hello", "Delegate");
        Console.WriteLine(response);
    }
}

五、MulticastDelegate 多播委托

多播委托(MulticastDelegate)是指在一个委托中注册多个方法,在注册方法时可以在委托中使用加号运算符或者减号运算符来实现添加或撤销方法。

创建一个方法集合类

c#">public class DelegateMethod
{
     public static void Method1()
     {
          Console.WriteLine("委托方法一.");
      }

      public void Method2() 
      {
          Console.WriteLine("委托方法二.");
      }

      public void Method3()
      {
          Console.WriteLine("委托方法三.");
      }
}

创建一个多播委托

c#">public class Program 
{
    public delegate void OrderDelegate();
    public static void Main(string[] args) 
    {
        OrderDelegate orderDelegate = new OrderDelegate(DelegateMethod.Method1);
        orderDelegate += new DelegateMethod().Method2;
        orderDelegate += new DelegateMethod().Method3;
        orderDelegate();
    }
}

输出

c#">委托方法一.
委托方法二.
委托方法三.

六、匿名方法

匿名方法(Anonymous methods)提供了一种传递代码块作为委托参数的技术。匿名方法是没有名称只有主体的方法。

在匿名方法中您不需要指定返回类型,它是从方法体内的return语句推断的。

.net 3.0以前的版本,匿名方法是通过使用delegate关键字创建委托实例来声明的

c#">delegate void ValueChange(int n);
...
ValueChange vchange=delegate(int x)
{
    Console.WriteLine("Anonymous Method:{0}",x);
}

对于高于C#3.0 的版本中,可以用Lambda表达式进行取代匿名方法,并用Lambda表达式作为编写内联代码的首选方式,因为它更简洁。

c#">button1.Click+=delegate(Object o,EventArgs e)
{
    Console.WriteLine("Anonymous Method:");
}

七、匿名委托之Action

Action是.NET Framework内置的泛型委托,可以使用Action委托以参数形式传递方法,而不用显示声明自定义的委托。封装的方法必须与此委托定义的方法签名相对应。也就是说,封装的方法必须具有一个通过值传递给它的参数,并并且不能有返回值。

Action的特点:

  1. 参数个数0~16
  2. 没有返回值
c#">public class ActionDemo
{
    public void Operate() 
    {
        Action action1 = new Action(Method1);
        Action<int, int> action2 = new Action<int, int>(Method2);
        action1();
        action2(1, 2);
        Action<int ,string,string> action3= delegate (int i1 ,string i2,string s){
            Console.WriteLine($"这里是三个参数的Action委托,参数1的值是:{i1},参数2的值是:{i2},参数3的值是:{s}");
        };
        action3(1,"a","abc");
    }
    public void Method1() 
    {
        Console.WriteLine("This Method1");
    }
     public void Method2(int a,int b) { Console.WriteLine("This Method2"); }
 }

八、匿名委托之Func

Func匿名委托与Action相似,但是Func委托代表有返回类型的委托。

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

Func 表示没有输入参参,返回值为int类型的委托。

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

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

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

public void Operate() 
{
    // 无参数,只要返回值 
    Func<int> fun1 = new Func<int>(FunWithNoPara);
    int result1 = fun1();
    Console.WriteLine(result1);
    Console.WriteLine("----------------------------");
    Func<int> fun2 = delegate { return 19; };
    int result2 = fun2();
    Console.WriteLine(result2);
    Console.WriteLine("----------------------------");
    Func<int> fun3 = () => { return 3; };
    int result3 = fun3();
    Console.WriteLine(result3);
    Console.WriteLine("----------------------------");
    //有一个参数,一个返回值
    Func<int, int> fun4 = new Func<int, int>(FunWithPara);
    int result4 = fun4(4);
    Console.WriteLine($"这里是一个参数一个返回值的方法,返回值是:{result4}");
    Console.WriteLine("----------------------------");
    // 使用委托
    Func<int, string> fun5 = delegate (int i) { return i.ToString(); };
    string result5 = fun5(5);
    Console.WriteLine($"这里是一个参数一个返回值的委托,返回值是:{result5}");
    Console.WriteLine("----------------------------");
    // 使用匿名委托
    Func<int, string> fun6 = (int i) =>
    {
         return i.ToString();
    };
    string result6 = fun6(6);
    Console.WriteLine($"这里是一个参数一个返回值的匿名委托,返回值是:{result6}");
    Console.WriteLine("----------------------------");
    // 多个输入参数
    Func<int, string, bool> fun7 = new Func<int, string, bool>(FunWithMultiPara);
    bool result7 = fun7(2, "2");
    Console.WriteLine($"这里是有多个输入参数的方法,返回值是:{result7}");
    Console.WriteLine("----------------------------");
    // 使用委托
     Func<int, string, bool> fun8 = delegate (int i, string s)
    {
        return i.ToString().Equals(s) ? true : false;
    };
    bool result8 = fun8(2, "abc");
    Console.WriteLine($"这里是有多个输入参数的委托,返回值是:{result8}");
    Console.WriteLine("----------------------------");
    // 使用匿名委托
    Func<int, string, bool> fun9 = (int i, string s) =>
    {
        return i.ToString().Equals(s) ? true : false;
    };
    bool result9 = fun9(45, "ert");
    Console.WriteLine($"这里是有多个输入参数的匿名委托,返回值是:{result9}");
    Console.ReadKey();
   }
   public int FunWithNoPara()
   {
       return 10;
   }

   public int FunWithPara(int i)
   {
       return i;
   }

   public bool FunWithMultiPara(int i, string s)
   {
       return i.ToString().Equals(s) ? true : false;
   }

九、委托总结

  1. 委托封装了包含特殊返回值和一组参数行为,类似于单一方法接口。
  2. 委托类型声明中描述的类型签名决定了方法哪个方法可用于委托实例,同时也决定了调用签名。
  3. 创建委托实例,需要一个方法以及(对于实例方法来说)调用方法的目标。
  4. 委托实例是不易变的。
  5. 每个委托实例都包含一个调用列表——一个操作列表。
  6. 委托实例可以合并到一起,也可以从一个委托实例中删除另一个。

十、参考资料

https://learn.microsoft.com/zh-cn/dotnet/api/system.func-1?view=net-7.0

https://learn.microsoft.com/zh-cn/dotnet/csharp/programming-guide/delegates/


http://www.niftyadmin.cn/n/5222797.html

相关文章

好用的产品经理学习网站

官网&#xff1a;https://www.pmmaster.cc 在官网注册登录后&#xff0c;可以下面免费的产品高质量资源 PRDView&#xff1a;http://www.prdview.cn 产品需求文档工具&#xff0c;帮助产品经理撰写高质量产品需求文档&#xff0c;高效率输出结构化产品需求 工具箱&#xff…

KMP算法【数据结构】

KMP算法 KMP算法是一种改进的字符串匹配算法 Next[j] k :一个用来存放子串返回位置的数组&#xff0c;回溯的位置用字母k来表示。其实就是从匹配失败位置&#xff0c;找到他前面的字符串的最大前后相等子串长度。默认第一个k值为-1(Next[0] -1),第二个k值为0(Next[1] 0),我…

指针数组用指针变量模拟二维数组

指针数组 指针数组是指针还是数组&#xff1f;&#xff1f; 整型数组&#xff1a;数组中的每个元素都是整型 字符数组&#xff1a;数组中的每个元素都是字符 指针数组&#xff1a;数组中的每个元素都是指针 #include<stdio.h> int main() { int a 10; int* …

第七节HarmonyOS UIAbility生命周期以及启动模式

一、UIAbility生命周期 为了实现多设备形态上的裁剪和多窗口的可扩展性&#xff0c;系统对组件管理和窗口管理进行了解耦。UIAbility的生命周期包括Create、Foreground、Background、Destroy四个状态&#xff0c;WindowStageCreate和WindowStageDestroy为窗口管理器&#xff08…

【Python百宝箱】密码学之美:Python安全性实战手册

前言 在当今数字化时代&#xff0c;数据安全和隐私保护是至关重要的。密码学作为信息安全的基石&#xff0c;为我们提供了许多关键的工具和算法&#xff0c;用于加密、解密、数据完整性验证和密码管理。Python生态系统中有多个强大的密码学库&#xff0c;本文将深入探讨其中一…

第一章[环境搭建]1.4:windows安装python

一,下载python 访问官网: Welcome to Python.orgThe official home of the Python Programming Languagehttps://www.python.org/ 如图:点击downloads这个链接 从页面上的各个链接中选取适用于自己电脑的版本 确定要下载版本之后,选到相应的架构安装包,现在的windows一般…

振南技术干货集:znFAT 硬刚日本的 FATFS 历险记(8)

注解目录 1、znFAT 的起源 1.1 源于论坛 &#xff08;那是一个论坛文化兴盛的年代。网友 DIY SDMP3 播放器激起了我的兴趣。&#xff09; 1.2 硬盘 MP3 推了我一把 &#xff08;“坤哥”的硬盘 MP3 播放器&#xff0c;让我深陷 FAT 文件系统不能自拔。&#xff09; 1.3 我…