【.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/


目录
相关文章
|
5月前
|
开发框架 .NET C#
ASP.NET Core Blazor 路由配置和导航
大家好,我是码农刚子。本文系统介绍Blazor单页应用的路由机制,涵盖基础配置、路由参数、编程式导航及高级功能。通过@page指令定义路由,支持参数约束、可选参数与通配符捕获,结合NavigationManager实现页面跳转与参数传递,并演示用户管理、产品展示等典型场景,全面掌握Blazor路由从入门到实战的完整方案。
503 6
|
开发框架 .NET 开发者
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:&lt;https://github.com/khellang/Scrutor&gt;
430 5
|
C# Android开发 iOS开发
2025年全面的.NET跨平台应用框架推荐
2025年全面的.NET跨平台应用框架推荐
682 23
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
372 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
开发框架 算法 中间件
ASP.NET Core 中的速率限制中间件
在ASP.NET Core中,速率限制中间件用于控制客户端请求速率,防止服务器过载并提高安全性。通过`AddRateLimiter`注册服务,并配置不同策略如固定窗口、滑动窗口、令牌桶和并发限制。这些策略可在全局、控制器或动作级别应用,支持自定义响应处理。使用中间件`UseRateLimiter`启用限流功能,并可通过属性禁用特定控制器或动作的限流。这有助于有效保护API免受滥用和过载。 欢迎关注我的公众号:Net分享 (239字符)
353 1
|
开发框架 缓存 .NET
GraphQL 与 ASP.NET Core 集成:从入门到精通
本文详细介绍了如何在ASP.NET Core中集成GraphQL,包括安装必要的NuGet包、创建GraphQL Schema、配置GraphQL服务等步骤。同时,文章还探讨了常见问题及其解决方法,如处理复杂查询、错误处理、性能优化和实现认证授权等,旨在帮助开发者构建灵活且高效的API。
417 3
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
347 5
|
JSON 算法 安全
JWT Bearer 认证在 .NET Core 中的应用
【10月更文挑战第30天】JWT(JSON Web Token)是一种开放标准,用于在各方之间安全传输信息。它由头部、载荷和签名三部分组成,用于在用户和服务器之间传递声明。JWT Bearer 认证是一种基于令牌的认证方式,客户端在请求头中包含 JWT 令牌,服务器验证令牌的有效性后授权用户访问资源。在 .NET Core 中,通过安装 `Microsoft.AspNetCore.Authentication.JwtBearer` 包并配置认证服务,可以实现 JWT Bearer 认证。具体步骤包括安装 NuGet 包、配置认证服务、启用认证中间件、生成 JWT 令牌以及在控制器中使用认证信息
573 2
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
543 5
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
328 7