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

简介: 笔记

一、概述


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


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


二、委托(Delegate)定义


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

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


声明委托步骤

1.声明一个delegate对象,它应当与要传统的方法具有相同的参数和返回值类型。

2.创建delegate对象,new Delegate传入参数

3.通过delegate调用方法,并返回值。


代码演示

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) - 无返回值委托


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) - 有返回值委托


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)是指在一个委托中注册多个方法,在注册方法时可以在委托中使用加号运算符或者减号运算符来实现添加或撤销方法。

创建一个方法集合类

public class DelegateMethod
{
     public static void Method1()
     {
          Console.WriteLine("委托方法一.");
      }
      public void Method2() 
      {
          Console.WriteLine("委托方法二.");
      }
      public void Method3()
      {
          Console.WriteLine("委托方法三.");
      }
}

创建一个多播委托

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();
    }
}

输出

委托方法一.
委托方法二.
委托方法三.

六、匿名方法


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


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


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

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

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

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

七、匿名委托之Action


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


Action的特点:

1.参数个数0~16

2.没有返回值

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类型的委托。


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


Func 表示传入参数为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/


目录
相关文章
|
1月前
|
消息中间件 前端开发 小程序
一个基于.NET Core构建的简单、跨平台、模块化的商城系统
今天大姚给大家分享一个基于.NET Core构建的简单、跨平台、模块化、完全开源免费(MIT License)的商城系统:Module Shop。
|
1月前
|
算法 C# 数据库
【干货】一份10万字免费的C#/.NET/.NET Core面试宝典
C#/.NET/.NET Core相关技术常见面试题汇总,不仅仅为了面试而学习,更多的是查漏补缺、扩充知识面和大家共同学习进步。该知识库主要由自己平时学习实践总结、网上优秀文章资料收集(这一部分会标注来源)和社区小伙伴提供三部分组成。该份基础面试宝典完全免费,发布两年来收获了广大.NET小伙伴的好评,我会持续更新和改进,欢迎关注我的公众号【追逐时光者】第一时间获取最新更新的面试题内容。
|
1月前
|
数据可视化 网络协议 C#
C#/.NET/.NET Core优秀项目和框架2024年3月简报
公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍、功能特点、使用方式以及部分功能截图等(打不开或者打开GitHub很慢的同学可以优先查看公众号推文,文末一定会附带项目和框架源码地址)。注意:排名不分先后,都是十分优秀的开源项目和框架,每周定期更新分享(欢迎关注公众号:追逐时光者,第一时间获取每周精选分享资讯🔔)。
|
12天前
|
C# Windows
一款.NET开源、简洁易用的Windows桌面小说阅读应用
一款.NET开源、简洁易用的Windows桌面小说阅读应用
|
14天前
|
开发框架 物联网 测试技术
【专栏】.NET 开发:打造领先应用的基石
【4月更文挑战第29天】本文探讨了.NET开发框架为何成为构建领先应用的首选。高性能与稳定性是.NET的核心优势,它采用先进的技术和优化策略,如.NET Core的轻量级设计和JIT/AOT编译模式。跨平台兼容性让开发者能用相同代码库在不同操作系统上构建应用。现代化的开发体验,如C#语言的创新特性和Visual Studio的强大工具,提升了开发者生产力。丰富的生态系统和广泛支持,包括庞大的开发者社区和微软的持续投入,为.NET提供了坚实后盾。
|
14天前
|
机器学习/深度学习 人工智能 Cloud Native
【专栏】洞察.NET 技术的前沿应用
【4月更文挑战第29天】本文探讨了.NET技术的前沿应用,包括.NET Core的跨平台崛起、云原生及AI/机器学习领域的整合。.NET Core支持多平台运行,开源社区的参与促进了其快速发展和性能优化。Xamarin与.NET MAUI助力跨平台移动应用和统一界面开发,而云原生应用借助.NET Core与Azure云服务得以轻松构建和部署。此外,ML.NET和TensorFlow.NET为.NET开发者提供了机器学习和深度学习工具,推动智能应用和边缘计算的创新。.NET技术正持续演进,引领软件开发新趋势。
|
14天前
|
人工智能 物联网 开发者
【专栏】探究.NET 技术的创新应用
【4月更文挑战第29天】本文探讨了.NET技术的最新进展和创新应用,包括.NET 5及后续版本的统一平台、性能提升、跨平台支持、云集成优化和开源社区的贡献。在创新应用场景中,重点介绍了微服务架构、物联网、AI、游戏开发和移动应用。未来,.NET将持续优化性能,深化云原生应用,集成新兴技术,扩大社区生态,并促进相关教育和培训。开发者应把握.NET技术的潜力,积极参与其发展,创造更多创新软件产品。
|
14天前
|
安全 Linux API
【专栏】.NET 开发:打造卓越应用的秘诀
【4月更文挑战第29天】本文介绍了.NET技术的起源、核心特性和应用场景,揭示了其打造卓越应用的秘诀。自2002年推出,.NET历经发展,现支持跨平台,包括.NET Core和.NET 5。其核心特性包括:跨平台兼容性、面向对象编程、内置安全性和高效性能。丰富的类库、强大的开发工具、简洁的语言语法以及活跃的社区支持,使.NET成为构建高效、安全应用的理想选择。随着技术进步,.NET将持续赋能开发者创造更多可能性。
|
14天前
|
人工智能 安全 API
【专栏】理解 .NET 技术,打造优质应用
【4月更文挑战第29天】本文探讨了如何利用.NET技术构建高质量应用程序,介绍了.NET从2002年发展至今的历程,强调其跨平台能力、高效开发、丰富的类库和API、开源生态及安全性等优势。随着.NET 6的规划,平台将更加统一和跨平台,适应云计算、AI等新兴技术。.NET凭借其特性,成为开发者和企业创新的有力工具,未来将继续扮演重要角色。
|
14天前
|
机器学习/深度学习 自然语言处理 安全
【专栏】.NET 开发:构建智能应用的关键
【4月更文挑战第29天】本文探讨了.NET开发在构建智能应用中的关键作用,强调了其强大的框架、工具集、高效性能和跨平台支持。通过实例展示了.NET在人工智能、物联网及企业级应用中的应用。同时,指出了.NET开发面临的挑战,如技术更新的学习成本、性能优化、资源管理和安全隐私保护,并提出了应对策略。随着技术进步,.NET将在智能应用领域发挥更大作用,推动创新与便利。