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

news2024/9/22 19:25:00

我是荔园微风,作为一名在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://www.coloradmin.cn/o/1440865.html

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

相关文章

Ajax+JSON学习一

AjaxJSON学习一 文章目录 前言一、Ajax简介1.1. Ajax基础1.2. 同源策略 二、Ajax的核心技术2.1. XMLHttpRequest 类2.2. open指定请求2.3. setRequestHeader 设置请求头2.4. send发送请求主体2.5. Ajax取得响应 总结 前言 一、Ajax简介 1.1. Ajax基础 Ajax 的全称是 Asynchron…

网络连接受限或无连接怎么办?这里提供几个修复办法

本文介绍了如何完成疑难解答步骤,以解决在Windows 10、Windows 8和Windows 7中尝试在Windows计算机上设置或建立网络连接时可能遇到的连接问题错误。 可能错误提示 连接受限或无连接:连接具有有限的连接或无连接。你可能无法访问Internet或某些网络资源。 连接受限。 排除和解…

神经网络基本原理

神经网络是一门重要的机器学习技术。它是目前最为火热的研究方向–深度学习的基础。 神经网络是一种模拟人脑的神经网络以期能够实现类人工智能的机器学习技术。人脑中的神经网络是一个非常复杂的组织。成人的大脑中估计有1000亿个神经元之多。 1 介绍 下面是一个包含三个层…

百度Apollo荣获量子位-智能车参考“2023智能车年度评选”两大奖项

2023,是谁在引领智能车浪潮? 量子位-智能车参考发布“2023智能车年度评选”结果。经过业内专业评审和垂直社群万人票选后,百度Apollo荣获「年度十大智能车技术产品/方案」「年度十大智能车领军人物」两项大奖。 年度十大智能车技术产品\方…

二叉树中的最大路径和

124. 二叉树中的最大路径和 - 力扣(LeetCode) 思路 路径每到一个节点,有 3 种选择:1. 停在当前节点。2. 走到左子节点。3. 走到右子节点。走到子节点,又面临这 3 种选择,递归适合处理这种规模不同的同一问…

Redis 单线程

文章目录 Redis单线程架构Redis 单线程访问速度IO多路复用原理 Redis单线程架构 Redis的单线程架构的效果为:Redis的单线程是对于服务端而言的,Redis允许多个Redis用户端同时在线操作,但同时只有一个用户端在和服务端交互。多个用户同时发送…

生成验证码-超简单

引言 在Web开发中,验证码是一种常见的防止恶意破解、自动化提交的有效手段。在Java项目中,我们可以使用Hutool工具库快速实现验证码功能。Hutool是一个Java工具包,它以简洁易用著称,其中包含了验证码模块,可以让我们轻…

158基于matlab的用于分析弧齿锥齿轮啮合轨迹的程序

基于matlab的用于分析弧齿锥齿轮啮合轨迹的程序,输出齿轮啮合轨迹及传递误差。程序已调通,可直接运行。 158 matlab 弧齿锥齿轮啮合轨迹 传递误差 (xiaohongshu.com)

U3D记录之FBX纹理丢失问题

今天费老大劲从blender建了个模型,然后导出进去unity 发现贴图丢失 上网查了一下 首先blender导出要改设置 这个path mode要copy 然后unity加载纹理也要改设置 这里这个模型的纹理load要改成external那个模式 然后就有了,另外这个导出还有好多选项可…

基于Robei EDA--实现串口通信

一、串口简介 串口作为常用的三大低速总线(UART、SPI、IIC)之一,在设计众多通信接口和调试时占有重要地位。但UART和SPI、IIC不同的是,它是异步通信接口,异步通信中的接收方并不知道数据什么时候会到达,所…

消息中间件:Puslar、Kafka、RabbigMQ、ActiveMQ

消息队列 消息队列:它主要用来暂存生产者生产的消息,供后续其他消费者来消费。 它的功能主要有两个: 暂存(存储)队列(有序:先进先出 从目前互联网应用中使用消息队列的场景来看,…

深入理解Netty及核心组件使用—上

目录 Netty的优势 为什么Netty使用NIO而不是AIO? Netty基本组件 Bootstrap、EventLoop(Group) 、Channel 事件和 ChannelHandler、ChannelPipeline ChannelFuture Netty入门程序 服务端代码 客户端代码 运行结果 Netty的优势 1. API 使用简单&#xff0c…

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

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

CS50x 2024 - Lecture 2 - Arrays

00:00:00 - Introduction 00:01:01 - Story Time 00:06:03 - Compiling make本身并不是编译器,实际上是一个自动运行编译器的程序,如c语言的clang clang -o hello hello.csrc/ $ clang -o hello hello_world.c /usr/bin/ld: /tmp/hello_world-67f51…

工作与生活平衡:在生活中寻找和谐

工作和生活是我们生活中不断交织的两个重要方面。对许多人来说,找到两者之间的完美平衡已经成为一个持久的挑战。然而,与其专注于平衡,更重要的是要认识到工作和生活并不是可以相互平衡的两个分离实体,而是一个相互影响的循环。正…

WebSocket+Http实现功能加成

WebSocketHttp实现功能加成 前言 首先,WebSocket和HTTP是两种不同的协议,它们在设计和用途上有一些显著的区别。以下是它们的主要特点和区别: HTTP (HyperText Transfer Protocol): 请求-响应模型: HTTP 是基于请求-响应模型的协…

Leetcode刷题笔记题解(C++):面试题 08.07. 无重复字符串的排列组合

思路:因为字符之间互不相同,故使用全排列的方式去解题; 字符串长度为n,将第一个字母分别与后面每一个字母进行交换,生成n种不同的全排列;再用第二个元素与后面每一个元素进行交换,生成n - 1种不…

Spring Authorization Server Spring Security密码加密

文章目录 一、修改密码编码器二、效果三、注意点1. RegisteredClient2. UserDetailsService 一、修改密码编码器 以BCryptPasswordEncoder举例。 直接将其注册成PasswordEncoder 的Bean即可。 Beanpublic PasswordEncoder passwordEncoder() {// 密码为明文方式 // ret…

【PTA浙大版《C语言程序设计(第4版)》|编程题】习题7-3 判断上三角矩阵(附测试点)

目录 输入格式: 输出格式: 输入样例: 输出样例: 代码呈现 测试点 上三角矩阵指主对角线以下的元素都为0的矩阵;主对角线为从矩阵的左上角至右下角的连线。 本题要求编写程序,判断一个给定的方阵是否…

图论与图数据应用综述:从基础概念到知识图谱与图智能

目录 前言1 图论基础概念1.1 节点度1.2 度分布1.3 邻接矩阵 2 探索图的高级概念2.1 最短路径的关键性2.2 图的直径与平均路径的意义2.3 循环与路径类型的多样性 3 深入探讨图的广泛应用领域3.1 知识图谱的知识管理3.2 图智能在复杂决策中的应用3.3 图数据挖掘与分析的多领域应用…