服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - c# 委托的常见用法

c# 委托的常见用法

2022-10-08 15:34厉致彤 C#

这篇文章主要介绍了c# 委托的常见用法,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下

  此篇文章是我一个小白对委托的理解和总结,请高手多多评判指教。

  委托就是一种后期绑定机制,说的直白点就是在调用的时候才去传递业务逻辑的一种算法。

委托的创建语法:

?
1
public delegate int Comparison<in T>(T left, T right);//官方给出的定义泛型委托的demo

  语法看似像声明一个变量或方法的签名,但实现上是在声明一个类型。编译器会生成一个派生自System.MulticastDelegate的类(而System.MulticastDelegate派生自System.Delegate),类型名与委托的名字相同,其中包含Invoke 、BeginInvoke和EndInvoke等方法。编译器还为这个新类型生成添加和删除处理业务,以便该类的客户端可以在实例的调用列表中添加和删除方法。

  委托可以被定义在类的内部、名称空间下(与类同级)和全局名称空间下(不推荐)。

?
1
2
3
4
5
6
7
8
9
10
11
12
//在全局定义
public delegate int Comparison<in T>(T left, T right);
namespace Test
{
  //在指定名称空间下定义
  public delegate int Comparison2<in T>(T left, T right);
  public class Student
  {
    //在类内部定义
    public delegate int Comparison3<in T>(T left, T right);
  }
}

委托的定义赋值

  将委托当成类使用(委托本身就是一个类)。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//定义委托
public delegate int Comparison<in T>(T left, T right);
public class Test
{
  //定义
  private Comparison<int> comparator;
  public void Show()
  {
    //赋值 请注意,使用的是方法名称,不带括号,将方法附加给委托作为委托的调用方法。
    this.comparator = Compare;
    //调用
    this.comparator(1, 2);     //调用方式二    this.comparator.Invoke(1, 2);
  }
  private int Compare(int left, int right) => left.CompareTo(right);
}

当用作委托的目标方法是“小方法”的情况下,通常使用lambda表达式语法来执行赋值:

?
1
Comparison<string> comparer = (left, right) => left.Length.CompareTo(right.Length);

 多播委托

  通常只是将单个目标方法附加到委托。但是,委托对象确实支持将多个目标方法附加到一个委托对象的调用列表,称为多播委托。多播委托意味着通过委托调用时可以调用多个方法,所以可以为委托附加多个方法。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
private int Cal(int num) {return num * num;}
private void button1_Click(object sender, EventArgs e)
{
   Func<int, int> action = null;
   //使用+= 或 -= 来增加或移除委托实例
   action += a => { Console.WriteLine($"第{1}次执行" + a); return a + 1; };
   action += Cal;
   action += a => { Console.WriteLine($"第{3}次执行" + a); return a + 3; };
   action -= Cal;
   //如果有返回值的话,返回的是最后一次执行的结果
   int a = action(5);
   Console.WriteLine(a);
}

常用泛型委托

无返回值

?
1
2
3
4
public delegate void Action();
public delegate void Action<in T>(T arg);
public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
// Other variations removed for brevity.

有返回值

?
1
2
3
4
public delegate TResult Func<out TResult>();
public delegate TResult Func<in T1, out TResult>(T1 arg);
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
// Other variations removed for brevity

返回bool类型

?
1
public delegate bool Predicate<in T>(T obj);

注意:在.net core平台中,不支持委托目标方法的异步调用(即不支持BeginInvoke方法):

?
1
2
3
4
5
Action action = () => Console.WriteLine("委托执行了");
AsyncCallback asyncCallback = a => Console.WriteLine("回调执行了" + a);
//System.PlatformNotSupportedException:“Operation is not supported on this platform.”
IAsyncResult result = action.BeginInvoke(asyncCallback, "asdf"); //委托启动异步调用
action.EndInvoke(result);

 Event 事件

事件是带event关键字的委托的实例,event可以限制被外部调用(invoke)和直接赋值(=)。委托是一个类型,而事件是委托类型的一个实例。

  声明一个事件很简单,只需在声明一个委托对象时加上event关键字就行。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/// <summary>
/// 定义一个委托
/// </summary>
/// <param name="name"></param>
public delegate void ShowInfo(string name);
public class Study
{
  /// <summary>
  /// 声明一个事件
  /// </summary>
  public event ShowInfo ShowInfo;
  public void Show()
  {
    ShowInfo += Study_ShowInfo;
    //只能在“publisher”类中调用
    ShowInfo("asdf");
  }
  private void Study_ShowInfo(string name)
  {
    throw new NotImplementedException();
  }
}

可以在用事件的地方用委托来替代,但事件有一系列规则和约束用以保证程序的安全可控,事件只有 += 和 -= 操作,这样订阅者只能有订阅或取消订阅操作,没有权限执行其它操作。如果是委托,那么订阅者就可以使用 = 来对委托对象重新赋值(其它订阅者全部被取消订阅),甚至将其设置为null,甚至订阅者还可以直接调用委托,这些都是很危险的操作,广播者就失去了独享控制权。

事件保证了程序的安全性和健壮性。

以上就是c# 委托的常见用法的详细内容,更多关于c# 委托的资料请关注服务器之家其它相关文章!

原文链接:https://www.cnblogs.com/lizhitong/p/13502038.html

延伸 · 阅读

精彩推荐
  • C#c#设计模式 适配器模式详细介绍

    c#设计模式 适配器模式详细介绍

    结构模式(Structural Pattern)描述如何将类或者对象结合在一起形成更大的结构。结构模式描述两种不同的东西:类与类的实例。根据这一点,结构模式可以...

    C#教程网6982021-04-14
  • C#WPF自动隐藏的消息框的实例代码

    WPF自动隐藏的消息框的实例代码

    本文给大家介绍WPF自动隐藏的消息框实例代码,当鼠标放上去将一直显示,移开动画继续,提供normal和error两种边框。非常不错,具有参考借鉴价值,感兴...

    逆天の萌娃4532021-12-01
  • C#C#实现餐饮管理系统完整版

    C#实现餐饮管理系统完整版

    这篇文章主要为大家详细介绍了C#实现餐饮管理系统的完整版,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    战歌IT6452022-03-09
  • C#C#编程中设置程序只可被运行一次的方法

    C#编程中设置程序只可被运行一次的方法

    这篇文章主要介绍了C#编程中设置程序只可被运行一次的方法,包括一种让程序自动重启以限制第二次被运行的方法,需要的朋友可以参考下...

    jack_Meng11002021-11-03
  • C#C#基于Linq和反射实现数据持久化框架Xml4DB详解

    C#基于Linq和反射实现数据持久化框架Xml4DB详解

    在本篇文章里小编给大家整理的是关于C#基于Linq和反射实现数据持久化框架Xml4DB相关知识点,有需要的朋友们学习下。...

    PayneQin10022022-08-03
  • C#C#使用TcpListener及TcpClient开发一个简单的Chat工具实例

    C#使用TcpListener及TcpClient开发一个简单的Chat工具实例

    下面小编就为大家分享一篇C#使用TcpListener及TcpClient开发一个简单的Chat工具实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    cnc5122022-02-15
  • C#WPF实现2048小游戏

    WPF实现2048小游戏

    这篇文章主要为大家详细介绍了WPF实现2048小游戏,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    xddc8522022-02-20
  • C#C#编程自学之数据类型和变量一

    C#编程自学之数据类型和变量一

    本节课我们将学习C#编程语言的数据类型,数据类型可以分为值类型和引用类型,接着介绍变量的使用方法和作用域等内容,为了方便大家理解,我们还会...

    C#教程网12382021-10-29