C# 泛型委托和多播委托

泛型委托的定义

泛型委托的作用可以使程序定义一个委托,满足多个需求,如需要定义一个int类型参数的委托和定义一个string类型类型的委托时,直接使用泛型,就可以减少多次定义委托

泛型委托定义时候只需要再方法名后加:<类型在方法中的名字>

类型可以是多个,多个类型之间用 ”,“ 逗号隔开

// 定义泛型委托
delegate void MyDelegate<T>(T str);
// 定义返回值为泛型的委托
delegate Y MyDelegate1<T, Y>(T str);
// 实例化泛型委托
MyDelegate<string> md = (str) =>
{
    Console.WriteLine("泛型委托");
    Console.WriteLine("参数为:" + str);
};
MyDelegate1<string, int> md1 = (str) =>
{
    Console.WriteLine("有返回值的泛型委托");
    Console.WriteLine("参数为:" + str);
    return 1 + 1;
};

多播委托

多播委托也称为委托链,意思是委托的集合,使用+= 向集合中添加方法,使用-= 删除集合中的方法,在调用的时候统一调用

多播委托中的调用顺序不一定是添加的顺序

MyDelegate<string> md2 = new MyDelegate<string>(Method1);
md2 += Method2;
md2 += Method3;
md2 += Method4;
md2 += Method5;
md2 -= Method3;
md2("111"); 

多播委托的调用跟调用普通委托一样,使用实例名加括号。

以上的+=实际上在程序编译的时候会重新new一个委托,然后使用 Combine 将两个委托的调用列表连接在一起,返回一个新的委托列表

md2 = (MyDelegate<string>)Delegate.Combine(md2, new MyDelegate<string>(Method3));
Delegate.Combine 方法返回一个新的委托,但是类型是Delegate,Delegate是所有委托的父类,所以需要转换一下类型

多播委托的列表也可以被循环

foreach (Delegate @delegate in md2.GetInvocationList())
{
    ((MyDelegate<string>) @delegate)("123");
}
md2.GetInvocationList() 返回的是一个Delegate的数组,调用时候需要转换成MyDelegate系统委托系统委托

系统委托

有时候每次需要传递方法的时候都定义一个委托会有点麻烦,所以C#为我们定义了两个泛型委托 Action 和 Func

  • Action 表示可以有参数但是没有返回值的委托
  • Func 表示可以没有参数但是必须有返回值的委托

Action 使用时候有泛型和非泛型两种,非泛型为无参数无返回值的函数,有参数的方法在vs2017中最多是16个参数

Func 只有泛型的委托,Func只有一个参数时泛型为返回值的参数类型,有多个泛型参数时最后一个表示返回值的类型

// 无参数,无返回值
Action a = () => { };
// 多个参数,无返回值
Action<string, string> aciton = (s, s1) => { };
// 无参数,有返回值
Func<string> f = () => { return "fsa"; };
// 一个参数,有返回值
Func<string, int> func = s => { return 1; };


原文地址:https://www.cnblogs.com/sunhouzi/p/12299109.html

时间: 2024-08-06 17:15:20

C# 泛型委托和多播委托的相关文章

委托三------------多播委托与匿名方法

============================================多播委托 -------------------------------------主程序 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication3 {     class Pr

委托应用及泛型委托和多播委托

一.委托一般作为方法的参数或者返回值,或者使用多播委托(注册多个方法,可以全部触发) 1.示例:根据对于字符串不同的处理方法逻辑 private delegate void PrintString(string str); static void PrintStr( PrintString print,string str ) { print(str); } static void Method1(string str) { Console.WriteLine(str); } static vo

委托和多播委托

刚刚学习了委托的内容,先来说一下自己对委托的理解,权当是复习吧: 委托可以定义在类里面,也可以定义在类外面,如果定义在类里面就只能被这个类调用,不论声明它是public 还是private.如果定义在类外面就能被所有类调用.如果程序是多线程的,委托方法希望能在UI层调用,那么可以在命名空间下定义. //委托的声明 delegate关键字,这个委托只能代表返回值是空.参数是一个string类型的一个方法public delegate void GreetingDelegate(string nam

C# - 委托_多播委托

代码: 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace 委托_例子 8 { 9 static class Program 10 { 11 delegate void Show(string name); 12 13 static void CatShow(string

委托、泛型委托、多播委托 和 lamda表达式

委托基本概念:可以把一个方法作为一个参数传给另一个方法 声明:  方法前加 delegate  关键字 列子: using System; using System.Collections; using System.Collections.Generic; namespace Dome { class dom { static void Main(string[] args) { string[] sname = { "Abc", "dFg", "HjK

C# 委托之把委托从委托链(多播委托)移除

运用“-”运算符将委托从委托链移除 1 class HelloWorld 2 { 3 //定义委托类型 4 delegate void DelegationChain(); 5 static void Main(string[] args) 6 { 7 //用静态方法来实例委托 8 DelegationChain mydelegateone=new DelegationChain(HelloWorld.Fun2); 9 //用实例方法来实例委托 10 DelegationChain mydele

Net中委托之二多播委托

本篇主要讲解多播委托 1.多播委托的实例 public class MyDelegate { private delegate int NoParameterWithReturn();//1.声明委托 public static void Show() { NoParameterWithReturn method = new NoParameterWithReturn(ShowSomething);//2.委托的实例化 //多播委托 method += ShowSomething;//按顺序添加

C#多播委托

概述 在上一篇文章中,笔者就个人理解的委托做了简单的分享,本篇文章主要来说说多播委托.多播委托即每个委托可以包含多个方法. 理解多播委托 多播委托可以保护多个方法,但是在使用的时候需要注意:委托的签名必须是返回void,否则只能调用最后一个方法的得到结果.多播委托派生自System.MulticastDelegate类,System.MulticastDelegate类又派生自System.Delegate.System.MulticastDelegate的其他成员可以允许把多个方法调用链接为一

委托、Lambda表达式、事件系列04,委托链是怎样形成的, 多播委托

在"委托.Lambda表达式.事件系列01,委托是什么,委托的基本用法,委托的Method和Target属性"中,反编译委托,发现委托都是多播委托. 既然委托是多播委托,我们可以通过"+="把多个方法赋给委托变量,这样就形成了一个委托链, 它是怎样形成的?来看下面的例子: namespace ConsoleApplication3 { internal delegate void MySayDel(string msg); class Program { stati