首页 > 编程语言 >C#委托基础

C#委托基础

时间:2024-01-15 13:12:45浏览次数:27  
标签:调用 委托 C# void 基础 value int 方法

C#中的委托

委托可以认为是持有一个或者多个方法的对象,委托可以认为是一个类型安全的、面向对象的C/C++函数指针。如下例程序:

namespace CSharpProject1;

delegate void MyDelegate(int value); // 声明委托类型(没有返回值的类型,使用delegate, value为委托参数)

class Program
{
   static  void PrintLow(int value)
    {
        Console.WriteLine($"{value} - Low Value");
    }

    static void PrintHigh(int value)
    {
        Console.WriteLine($"{value} - High Value");
    }
    
    static void Main(string[] args)
    {
        MyDelegate myDelegate;  //  声明委托变量
        // 创建随机数生成器
        Random r = new Random();
        int randomValue = r.Next(99);
        // 创建一个包含PrintLow或者PrintHigh的委托对象并赋值给委托变量
        myDelegate = (randomValue < 50) ? new MyDelegate(Program.PrintLow) : new MyDelegate(Program.PrintHigh);
        // 执行委托传递参数
        myDelegate.Invoke(randomValue); 
    }
}

委托和类一样,是一种用户定义类型,但类表示的是数据和方法的集合,二委托则持有一个或者多个方法。使用委托方法如下:

  1. 声明一个委托类型。委托声明看上去和方法声明相似,只是没有实现块。
  2. 使用该委托类型声明一个委托变量。
  3. 创建一个委托类型的对象,委托方法包含指向某个方法的引用,这个方法的签名和返回类型必须跟第一步中定义的委托类型一致。
  4. 在代码中可以像调用方法一样调用委托。

调用委托

  • 可以通过两种方式调用委托。一种像是调用方法一样使用委托;另一种是使用委托的额Invoke方法。
  • 在传递参数时,可以直接将参数放在花括号里。
  • 在调用时委托不能为空(null),否则将引发异常,可以使用if语句来检查,也可以使用空条件运算符和Invoke方法。
  • 如果一个方法在调用列表中多次出现,则在调用委托时,每次在列表中遇到该方法时都会调用它。

委托的示例

没有返回值和参数的委托

namespace CSharpProject1;

// 定义一个没有返回值和参数的委托
delegate void PrintFunction();

class Test
{
    public void Print1()
    {
        Console.WriteLine("Print1 -- instance");
    }

    public static void Print2()
    {
        Console.WriteLine("Print2 -- static");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Test t = new Test();    // 创建一个测试类实例
        PrintFunction pf;       // 创建一个空委托
        pf = t.Print1;          // 实例化并初始化委托
        // 给委托增加3个另外的方法
        pf += Test.Print2;
        pf += t.Print1;
        pf += Test.Print2;
        // 现在委托有4个方法
        
        if (pf != null) pf();//调用委托
        else Console.WriteLine("Delegate is empty");
    }
}

调用带返回值的委托

如果委托有返回值并且在调用列表中有一个以上的方法,会发生下面的情况。

  • 调用列表中最后一个方法返回的值就是委托调用返回的值。
  • 委托列表中所有其他方法的返回值都会忽略。
namespace CSharpProject1;

// 定义一个有返回值的委托
delegate int MyDelegate();

class MyClass
{
    int value = 5;

    public int Add2()
    {
        value += 2;
        return value;
    }
    
    public int Add3()
    {
        value += 3;
        return value;
    }
}

class Program
{
    static void Main(string[] args)
    {
        MyClass mc = new MyClass();
        MyDelegate md = mc.Add2;
        md += mc.Add3;
        Console.WriteLine($"value: {md()}");
    }
}

调用带引用参数的委托

如果委托有引用参数,参数值会根据调用列表中的一个或者多个方法的返回值而改变。在调用委托列表中的下一个方法时,参数的新值(不是初始值)回传给下一个方法。例如:

namespace CSharpProject1;

// 定义一个没有回值带有参数的委托
delegate void MyDeleGate(ref int x);

class Program
{
    public void Add2(ref int x)
    {
        x += 2;
    }

    public void Add3(ref int x)
    {
        x += 3;
    }
    
    static void Main(string[] args)
    {
        Program p = new Program();
        MyDeleGate md = p.Add2;
        md += p.Add3;

        int x = 5;
        md.Invoke(ref x);
        Console.WriteLine($"value:{x}");
    }
}
D:/RiderProjects/CSharpProject1/CSharpProject1/bin/Debug/net8.0/CSharpProject1.exe
value:10

Process finished with exit code 0.

标签:调用,委托,C#,void,基础,value,int,方法
From: https://www.cnblogs.com/lilyflower/p/17965152

相关文章

  • XL6601系列ACMP模拟比较器使用
    目录模拟比较器(ACMP)简介特性实现结构框图Demo官方解释功能说明正输入与负输入输出输出标志中断设置与操作模拟比较器(ACMP)实现一个简单的小功能,掉电检测,使用到了ACMP外设,认为学习东西后总得产出点什么,所以在此简单记录一下。简介特性模拟比较器模块(ACMP)提供一个用于比较两......
  • Codeforces Round 919 (Div. 2)(A~D) 题解
    CodeforcesRound919(Div.2)(A~D)题解A.SatisfyingConstraints题意:给你一些条件让你求出满足条件的整数有多少个。模拟即可。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constllMAXN=2e5+5;llTex=1,n;voidAC(){ cin>>n; lll=......
  • 为什么C#要采用顶级语句?
    前言有群友问:为什么C#要采用顶级语句?.NET6发布后,C#10莫名引入了顶级语句,这是一种简化代码结构的语言特性。在此之前,C#程序必须包含一个入口点,通常是Main方法,然后在该方法中编写主要的程序逻辑。而使用顶级语句后,可以直接在文件的顶部编写执行代码,而无需显式地定义一个Main方法。......
  • 聊一聊为什么我要整合Microsoft.Extensions.DependencyInjection和Castle.Core
    前言如果用到动态代理,大家可能会有几种选择,排到前列的是Autofac+Castle、AspectCore和DoraInterception,我将从我当时研究的经历,以及我遇到的场景,为大家展示下聊一聊我为什么要费时费力的整合Microsoft.Extensions.DependencyInjection和Castle.Core当时遇到的场景直接上源码......
  • ChatGPT 淘金潮(全)
    原文:TheChatGPTGoldRush译者:飞龙协议:CCBY-NC-SA4.0一、ChatGPT简介什么是ChatGPT?ChatGPT是由OpenAI基于GPT-4架构创建的大型语言模型。它旨在理解和回应自然语言文本输入,使得可以与机器进行对话。ChatGPT已经在大量数据上进行了训练,使其能够对各种提示生成连贯......
  • 【Vue2+3入门到实战】(21)认识Vue3、使用create-vue搭建Vue3项目、熟悉项目和关键文件
    目录一、认识Vue31.Vue2选项式APIvsVue3组合式API2.Vue3的优势二、使用create-vue搭建Vue3项目1.认识create-vue2.使用create-vue创建项目三、熟悉项目和关键文件四、总结一、认识Vue31.Vue2选项式APIvsVue3组合式API<script>exportdefault{data(){r......
  • 【Vue2+3入门到实战】(23)Vue3之组合式API - 父子通信、模版引用、provide和inject、Vue
    这里写自定义目录标题一、组合式API-父子通信1.父传子2.子传父二、组合式API-模版引用1.基本使用2.defineExpose三、组合式API-provide和inject1.作用和场景2.跨层传递普通数据3.跨层传递响应式数据4.跨层传递方法四、Vue3.3新特性-defineOptions五、Vue3.3新特性......
  • 【JaveWeb教程】(2)Web前端基础:JavaScript入门不再难:一篇文章教你轻松搞定JavaScript的
    目录1介绍2引入方式3基础语法3.1书写语法3.2变量3.3数据类型和运算符4函数4.1第一种定义格式4.2第二种定义格式html完成了架子,css做了美化,但是网页是死的,我们需要给他注入灵魂,所以接下来我们需要学习JavaScript,这门语言会让我们的页面能够和用户进行交互。1介绍通过代......
  • 【JaveWeb教程】(1)Web前端基础:HTML+CSS入门不再难:一篇文章教你轻松搞定HTML与CSS!
    目录1.前端开发介绍2.HTML&CSS2.1HTML快速入门2.1.1操作2.1.2总结2.2开发工具2.3基础标签&样式2.3.1新浪新闻-标题实现2.3.1.1标题排版2.3.1.1.1分析2.3.1.1.2标签2.3.1.1.2实现2.3.1.2标题样式2.3.1.2.1CSS引入方式2.3.1.2.2颜色表示2.3.1.2.3标题字体颜色2.......
  • [转帖]oracle导出千万级数据为csv格式
    当数据量小时(20万行内),plsqldev、sqlplus的spool都能比较方便进行csv导出,但是当数据量到百万千万级,这两个方法非常慢而且可能中途客户端就崩溃,需要使用其他方法。一、sqluldr2工具1.优缺点优点:高效;支持功能较多;用户只需有对应表查询权限;可以在从库执行缺点:目前已没有再维......