微软.NET6开发的C#特性——委托和事件

我是荔园微风,作为一名在IT界整整25年的老兵,看到不少初学者在学习编程语言的过程中如此的痛苦,我决定做点什么,下面我就重点讲讲微软.NET6开发人员需要知道的C#特性,然后比较其他各种语言进行认识。

C#经历了多年发展, 进行了多次重大创新, 大幅优化了开发者的编码体验。在.NET 平台移交给.NET基金会运营后, C#更新的越来越不像原来的C#了,但总体上来说,所有改进依然以优化开发者的编码体验为最终目的。

首先,要记住一张表,如下:

C#版本     发布时间         .NET版本                       VS版本                  CLR版本

C#1.0        2002-2           .NET Framework 1.0     VS.NET 2002      .NET Framework CLR 1.0

C#2.0        2005-11         .NET Framework 2.0     VS2005               .NET Framework CLR 2.0

C#3.0        2006-11         .NET Framework 3.0     VS2008               .NET Framework CLR 2.0 

C#3.0       2007-11          .NET Framework 3.5     VS2008                .NET Framework CLR 2.0 

C#4.0       2010-4           .NET Framework 4.0     VS2010                .NET Framework CLR 4.0

C#5.0       2012-2           .NET Framework 4.5     VS2012               .NET Framework CLR 4.0

C#6.0       2015-7           .NET Framework 4.6      VS2015              .NET Framework CLR 4.0

C#7.0       2016-8           .NET Framework 4.6.2    VS2017(v15)     .NET Framework CLR 4.0

C#7.1       2017-4           .NET Framework 4.7      VS2017(v15.3)   .NET Framework CLR 4.0

C#7.2       2017-10         .NET Framework 4.7.1   VS2017(v15.5)    .NET Framework CLR 4.0

C#7.3       2018-4           .NET Framework 4.7.2   VS2017(v15.8)   .NET Framework CLR 4.0

C#8.0       2019-4           .NET Framework 4.8    VS2019(v16.3)    .NET Framework CLR 4.0

C#8.0       2019-9           .NETCore 3.0                 VS2019(v16.4)    .NETCore CLR 3.0       

C#9.0       2020-11          .NET 5.0                        VS2019(v16.8)    .NET CLR 5.0           

C#10.0     2021-11          .NET 6.0                        VS2022(v17)       .NET CLR 6.0 

看完这张表,我真的是很感慨,从测试版开始,我居然陪伴着.NET和C#走过了二十多年,我不知道有没有微软公司的人在看这篇文章,如果有的话,不知道我这样的二十多年的.NET和C#程序员有没有机会去微软中国和微软亚洲研究院的总部去参观一下,去坐一坐,并作一下技术交流。二十多年了,人生又有几个二十多年啊。

.NET平台是基于IL中间语言的应用运行环境,面向对象语言C#是平台的主要开发语言。除此之外还有同样面向对象的C++/CLI。C++/CLI主要用于和原生C++交互,在.NET平台中仅支持Windows系统。

C#和.NET平台本来是微软为了与Java平台竞争而打造的,C#在设计时充分总结了Java的经验教训,解决了大量Java的基本设计缺陷。本着为一线开发者谋实惠的宗旨,C#设计了大量能减轻开发者的编写负担、容易理解且安全高效的实用功能。为了尽可能降低因安全措施导致性能大幅下降的影响,C#还在有限的情况下保留了C/C++语言的部分语法和功能。到了.NET时代,微软依然在运行时(Runtime)和语言两边同时进行着优化。

随着上世纪九十年代Java的发布,软件公司和开发者开始感受到基于虚拟机的托管语言所带来的好处,微软也不甘示弱,在2001年发布了.NET Framework平台和C#。提供了完整的基础面向对象支持。

委托

委托可以说是C#的一个强大特性。委托这个概念其实是来源于C语言的函数指针,又在面向对象的方面里完成了升级。C语言的函数指针能完成各种非常有效的功能,最典型的就是回调函数,可以说事件驱动的图形界面编程的基石就是函数指针。但是C语言的函数指针可能会导致各种bug,甚至黑客入侵时很多时候也是瞄着函数指针下手。

因为C语言从不验证函数指针所指向的函数。C#开发团队深知函数指针的重要性,必须想办法控制住函数指针,否则后患无穷,因此最终诞生了委托。

委托本身也是一种类型,但是和结构体一样,有专门的定义语法。在方法声明头部的返回类型之前加上访问修饰和delegate关键字就能完成委托类型的定义。委托类型的所有成员都统一由编译器生成。委托是面向对象的函数指针,可以同时保持对方法和目标对象的引用。同时委托又是强类型的,会严格验证所引用的方法签名和委托支持的签名是否兼容。

微软又设计了多播委托,可以让一个委托对象同时引用多个方法,调用委托就能同时调用引用的所有方法,如果多播委托有返回值,只有最后一个委托的返回值有效。实际上所有自定义委托类都隐式派生自多播委托类,继承路径为: System.Object→System.Delegate→System.MulticastDelegate→各种自定义委托

而Java在面对函数指针时选择了删除函数指针。但这个功能本身是非常有必要的,怎么办呢?最后Java选择了用接口去模拟函数指针的功能,并取名叫函数式接口。但是接口不是专门为函数指针设计的,接口的“兼取”导致了函数指针的语义被接口掩盖了。

一个合格的函数式接口只能声明一个方法,但只声明了一个方法的接口却不一定是函数式接口。接口的冗长语法也让实现函数指针的功能变得非常麻烦,这一点稍微对比一下WinForm和安卓的事件处理器的模板代码就能看出来。

虽然后来Java8增加了Lambda表达式和方法引用功能,在一定程度上对代码有所简化,但C#在更早之前就增加了Lambda表达式功能并进行了持续更新。

C#、C和Java的委托定义语法的示例代码如下所示。

(1)C#

namespace Example
{public delegate string MyDelegate(string str1, string str2);class Program{public static void Main(string[] args){MyDelegate func1;}}
}

(2) C

//直接声明函数指针变量
char*(*func)(char* str1, char* str2);//先定义函数指针类型,再声明变量
typedef char* (*MyDelegate)(char* str1, char* str2);
MyDelegate func1;

从对比中可以看出C#的委托定义语法和C还是很像的。

(3)Java

package com. example. coredx. practice;@FunctionalInterface
public interface MyDelegate{String function(String str1, String str2);
}

Java中的 FunctionalInterface注解从 Java 8开始才有,之前的版本中只要接口中只定义一个方法即可,无法单纯从代码上分辨是函数式接口还是普通接口。

事件

事件是和委托配合使用的,为了确保使用事件的代码不会有意无意地调用或破坏委托,C#设计了事件。事件有点类似于属性,能确保只允许外部代码订阅或取消订阅事件,只允许类的内部成员调用触发。没有委托的Java自然无此问题。

C#的事件的示例代码如下:
 

using System;namespace Example
{//定义事件参数public class MyEventArgs : EventArgs{private DateTime striggeredTime;private string smessage;public DateTime TriggeredTime{get {return striggeredTime;}}public string Message{get {return smessage};}public MyEventArgs(string message){smessage= message;striggeredTime= DateTime. Now;}}//定义事件处理委托public delegate void MyEventHandler(object sender, MyEventArgs args);class Program{private static MyEventHandler smyEventHandler;//定义事件订阅访问器public static event MyEventHandler MyEvent{add { smyEventHandler += value; }remove { smyEventHandler -= value;}}//用简化语法定义事件订阅访问器public static event MyEventHandler MyEvent2;public static void Main(string[] args){if (smyEventHandler != null) smyEventHandler. Invoke (null,new MyEventArgs("程序已启动。");if (MyEvent2 != null) MyEvent2.Invoke(null, new MyEventArgs("程序已启动。"));}}
}

从上面中可以看出C#的event关键字实际上是在类中定义事件处理委托的注册和取消访问器,本质上还是方法,事件本身还是靠委托实现的。也正是因为事件只允许进行注册和取消注册,因此可以避免外部代码有意或无意地调用事件处理委托误触发事件或直接通过赋值破坏事件处理委托。

上面代码中的“object sender, MyEventArgs args”是微软推荐的事件处理模式, WinForm控件的大多数事件都是按照这个模式设计的。其中sender表示引发事件的对象,args表示事件携带的数据。

作者简介:荔园微风,1981年生,高级工程师,浙大工学硕士,软件工程项目主管,做过程序员、软件设计师、系统架构师,早期的Windows程序员,Visual Studio忠实用户,C/C++使用者,是一位在计算机界学习、拼搏、奋斗了25年的老将,经历了UNIX时代、桌面WIN32时代、Web应用时代、云计算时代、手机安卓时代、大数据时代、ICT时代、AI深度学习时代、智能机器时代,我不知道未来还会有什么时代,只记得这一路走来,充满着艰辛与收获,愿同大家一起走下去,充满希望的走下去。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2775162.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

回归预测 | Matlab实现WOA-CNN-LSTM-Attention鲸鱼算法优化卷积长短期记忆网络注意力多变量回归预测(SE注意力机制)

回归预测 | Matlab实现WOA-CNN-LSTM-Attention鲸鱼算法优化卷积长短期记忆网络注意力多变量回归预测(SE注意力机制) 目录 回归预测 | Matlab实现WOA-CNN-LSTM-Attention鲸鱼算法优化卷积长短期记忆网络注意力多变量回归预测(SE注意力机制&…

Java_栈_队列

文章目录 一、栈(Stack)1.概念2.栈的使用3.栈的模拟实现1、定义接口2、定义栈3、成员4、构造方法5、判断空间是否满 full6、入栈 push7、出栈 pop8、获取栈顶元素 peek9、获取栈中有效元素个数 size10、检测栈是否为空 empty完整代码 4.练习1、有效括号2…

单片机的省电模式及策略

目录 一、单片机省电的核心策略 二、单片机IO口的几种模式 三、单片机的掉电运行模式 (1) 浅谈cpu运行为什么会需要时钟? (2)STC15系列单片机内部可以配置时钟 (3)分频策略,降低…

车载自动化项目:Python

1. 自动化测试用的什么框架? 第一种:PythonSeleniumuittest框架 首先是拿到需求文档,基于这个需求去进行搭建。 用pytestrequestallure 这些第三方库进行编写自动化脚本。 举个例子一般的话整个的一个自动化的搭建是分为6层嘛&#xff1a…

Java学习笔记2024/2/8

面向对象 //面向对象介绍 //面向: 拿、找 //对象: 能干活的东西 //面向对象编程: 拿东西过来做对应的事情 //01-如何设计对象并使用 //1.类和对象 //2.类的几个不错注意事项 1. 类和对象 1.1 类和对象的理解 客观存在的事物皆为对象 ,所以我们也常常说万物皆对…

redhat grub.cfg配置文件丢失或报错解决

1.实验环境:把grub.cfg删除 [rootexample ~]# rm -rf /boot/grub2/grub.cfg 2.重启服务器 3,发现进入系统失败 输入以下命令 ls: 列出当前设备上的文件和目录。 grub> ls (hd0) (hd0,msdos3) (hd0,msd0s2) (hd0,msdos1) #一般第一个为/boot分区se…

2月8日作业

1、现有文件test.c\test1.c\main.c,编写Makkefile 代码: CCgcc EXEa.out OBJS$(patsubst %.c,%.o,$(wildcard *.c)) CFLAGS-c -oall:$(EXE)$(EXE):$(OBJS)$(CC) $^ -o $%.o:%.c$(CC) $(CFLAGS) $ $^.PHONY:cleanclean:rm $(OBJS) $(EXE)运行结果: 2、…

wyh的迷宫

涉及知识点:求迷宫能否到达终点的,而不是求路径数的,用bfs时可以不用重置状态数组(回溯)。 题目描述 给你一个n*m的迷宫,这个迷宫中有以下几个标识: s代表起点 t代表终点 x代表障碍物 .代…

【C#】创建Json文件并根据dll路径获取

创建Json文件 更改属性 【代码】根据dll路径获取 Assembly assembly Assembly.GetExecutingAssembly(); string assemblyPath assembly.Location; string relativeDllPath System.IO.Path.Combine(System.IO.Path.GetDirectoryName(assemblyPath), "Json\\test.json&q…

Kubernetes基础(十五)-k8s网络通信

1 k8s网络类型 2 Pod网络 2.1 同一pod内不同容器通信 Pod是Kubernetes中最小的可部署单元,它是一个或多个紧密关联的容器的组合,这些容器共享同一个网络命名空间和存储卷,因此Pod中的所有容器都共享相同的网络命名空间和IP地址——PodIP&a…

华为第二批难题五:AI技术提升六面体网格生成自动化问题

有CAE开发商问及OCCT几何内核的网格方面的技术问题。其实,OCCT几何内核的现有网格生成能力比较弱。 HybridOctree_Hex的源代码,还没有仔细去学习。 “HybridOctree_Hex”的开发者说:六面体网格主要是用在数值模拟领域的,比如汽车…

[WUSTCTF2020]朴实无华(特详解)

一开始说header出问题了 就先dirsaerch扫一遍 发现robot.txt 访问一下 去看看&#xff0c;好好好&#xff0c;肯定不是得 他一开始说header有问题&#xff0c;不妨抓包看看&#xff0c;果然有东西 访问看看&#xff0c;乱码修复一下&#xff0c;在之前的博客到过 <img src…

一文带你读懂Python线程

Python线程 进程有很多优点&#xff0c;它提供了多道编程&#xff0c;可以提高计算机CPU的利用率。既然进程这么优秀&#xff0c;为什么还要线程呢&#xff1f;其实&#xff0c;仔细观察就会发现进程还是有很多缺陷的。 主要体现在一下几个方面&#xff1a; 进程只能在一个时…

springboot基础案例(二)

文章目录 前言一.需求分析: 分析这个项目含有哪些功能模块二.库表设计(概要设计): 1.分析系统有哪些表 2.分析表与表关系 3.确定表中字段(显性字段 隐性字段(业务字段))2.1 创建一个库: ems-thymeleaf2.2 创建 2张表三.编码(环境搭建)1.创建一个springboot项目 项目名字: ems-t…

【Flink入门修炼】1-1 为什么要学习 Flink?

流处理和批处理是什么&#xff1f; 什么是 Flink&#xff1f; 为什么要学习 Flink&#xff1f; Flink 有什么特点&#xff0c;能做什么&#xff1f; 本文将为你解答以上问题。 一、批处理和流处理 早些年&#xff0c;大数据处理还主要为批处理&#xff0c;一般按天或小时定时处…

Java毕业设计-基于ssm的仓库管理系统-第76期

获取源码资料&#xff0c;请移步从戎源码网&#xff1a;从戎源码网_专业的计算机毕业设计网站 项目介绍 基于ssm的游泳馆管理系统&#xff1a;前端jsp、jquery、bootstrap&#xff0c;后端 springmvc、spring、mybatis&#xff0c;集成游泳课程报名、游泳卡在线售卖、购物车、…

可解释性AI(XAI):开启AI决策过程透明化,重塑信任与解决伦理偏见

文章目录 每日一句正能量前言可解释性AI的定义与重要性什么是可解释性&#xff1f;促进技术应用的可信度提高技术的透明度保护隐私和数据权益促进AI的社会接受度 可解释性AI的挑战与难点可解释性AI的应用场景后记 每日一句正能量 宁可因高目标而脖子硬&#xff0c;也不要为低目…

java并发执行批量插入

java并发执行批量插入 1、mybatis-plus批量插入 long start System.currentTimeMillis();int num 5000; //一次批量插入的数量int j 0;for (int i 0;i<20;i){List<User> userList new ArrayList<>();while (true){j;User user new User();user.setUserP…

从REPR设计模式看 .NET的新生代类库FastEndpoints的威力

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,我们面对的不仅仅是技术还有人心,人心不可测,海水不可量,唯有技术,才是深沉黑夜中的一座闪烁的灯塔 !序言 又到了一年年末,春节将至…

Maven私服部署与JAR文件本地安装

Nexus3 是一个仓库管理器&#xff0c;它极大地简化了本地内部仓库的维护和外部仓库的访问。 平常我们在获取 maven 仓库资源的时候&#xff0c;都是从 maven 的官方&#xff08;或者国内的镜像&#xff09;获取。团队的多人员同样的依赖都要从远程获取一遍&#xff0c;从网络方…