当前位置: 首页 > news >正文

微软.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++中升级为了面向对象的类。C++的类和结构体并没有明确的概念和功能上的差别,Java删除了结构体这个概念,只保留了类。微软发现了能够有效利用这两个概念的方法,因此C#保留了类和结构体。

Java和C#都有一套完善的类型系统,所有的类型都是直接或间接地由 Object派生而来。但不知为何Java有基元类型。基元类型基本代表了在C/C++中由编译器和CPU直接支持的原始类型,而这些类型却不属于类型系统。为了解决这个问题,Java又设计了一套包装类型。这带来一个问题,类型系统是Java的根基,但作为其中的基石的基元类型居然和类型系统不兼容,这也在后来为Java带来了更多的麻烦。

C#却巧妙地利用了类和结构体完成了没有内生矛盾的类型系统,一切类型都是Object的后代,包括基本数据类型。在C#的设计中,基本类型的继承路径是 System.Object→System.ValueType→各种基本类型。

ValueType禁止使用常规语法继承,并且其子类是强制封闭的,禁止继续继承。这时结构体就派上用场了,结构体就是隐式继承了ValueType的封闭类型,基本数据类型就是由.NET预定义的结构体。结构体是直接在线程栈上分配的免回收类型,拥有极高的性能。也因为在栈上的分配必须静态确定其占用的内存空间并直接分配,因此结构体禁止赋值为null。

由于结构体的复制策略是深拷贝,因此在方法之间作为参数传递时传递的是完整的独立副本,互不影响,和普通类的引用拷贝形成了鲜明的对比。为了保持和Object的完整兼容性,.NET还特地为结构体准备了自动装箱和拆箱。装箱即是指在显式或隐式转换为Object类型的时候运行时自动在托管堆上分配对象内存并把值复制到对象中;拆箱即是指在显式或隐式转换回原类型时自动在线程栈上分配内存并把值从托管堆复制到栈上。托管堆中的对象占用的内存一般比线程栈上的大,因为堆对象占用的内存除了基本值所需内存之外还包含类型对象指针和同步块索引(C#的lock同步锁语句块就是依靠同步块索引实现的)等额外信息,而栈上的结构体实例只占用基本值所需的内存。经过这些周密的设计,C#拥有了完美自治的类型系统,类和结构体也拥有了明显的功能区分。

在C++中有一个被称为友元类的功能,友元类之间允许相互访问对方的私有成员,这在一定程度上破坏了类的封装性,因此Java和C#都删除了这个功能。不过C#却有一个被称为友元程序集的功能,友元程序集的类之间允许互相访问对方的内部(internal)成员,这在编写单元测试时经常用到。由于C#和Java都是托管语言,因此都可以通过反射彻底绕过成员访问保护机制,C/C++也可以通过万能的指针绕过编译器保护。

C#、C、C++、Java的类和结构体的代码如下。

(1)C#

//结构体
public struct Point2D
{public double x;public double y;
}//类
public class Point3D{public double x;public double y;public double z; 
} //抽象类 
public abstract class MyClass 
{ public abstract void Method1(); public virtual void Method2() {} 
} 

(2)C

typedef struct {double x; double y; 
} Point 2D; 

(3)C++

① Point3D.h

#pragma once class Point3D 
{ public: double x; double y; double z; 
}; class MyClass 
{ public: virtual void Method1() =0; virtual void Method2();
};

② Point3D.cpp

#include"Point3D.h" void MyClass::Method2() {} 

(4) Java

public class Point3D { public double x; public double y; public double z; 
}public abstract class MyClass{ public abstract void method1(); public void method2() {}
} 

在C语言中有一种独特的数据结构叫作联合体,它的特点是所有数据成员共享内存空间,并且同一时刻最多只有一个成员处于可用状态。这种数据类型的诞生主要是因为C语言刚面世的时候计算机的内存还比较小, 需要尽量节约使用内存。C#和Java诞生的年代内存不再紧缺, 因此并不支持这种数据类型。但是C#为了兼容和C语言的互操作, 从.NET Framework 1.1开始支持通过特殊方式模拟联合体。 

C#在模拟联合体时,如果其中有类类型的成员,可能在运行时引发异常,因此在模拟联合体时一般只用结构体类型的成员,当然,虽然读取非激活状态的成员不会引发异常,但是仍然可能读取到错误的值。在C语言的联合体中通常也只使用基本数据类型。

C的联合体和C#的模拟联合体示例代码分别如下所示。

(1) C

typedef union {int x;float y;double z;
} MyUnion;


(2)C#

using System. Runtime.InteropServices;namespace Example
{//手动定义结构体布局,占用8字节空间[StructLayout (LayoutKind. Explicit, Size =8)]public struct MyUnion{//字段偏移量为0,实际占用4字节,剩下4字节不使用[Fieldoffset(0)]public int x;//字段偏移量为0,实际占用4字节,剩下4字节不使用[Fieldoffset(0)]public float y;//字段偏移量为0,刚好用完8个字节[Fieldoffset (0)]public double z;}
}

C#使用结构体模拟联合体时,StructLayout特性可以告知运行时(Runtime)开发者要手动定义结构体的内存布局,其中字段的FieldOffset特性告知运行时这个字段在对象中的内存偏移量,示例中全部指定为0就表示所有成员共享相同的内存空间。上面代码中的各个字段所需的内存空间不尽相同,因此当需求内存较小的成员处于激活状态时,多余的内存会处于空闲状态。
 

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

相关文章:

微软.NET6开发的C#特性——类、结构体和联合体

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

naiveui 上传图片遇到的坑 Upload

我在开发图片上传功能, 需要手动触发上传 但是我调用它内部自定义submit方法, 结果接口一直在报错400 我反反复复的测试了好就, 确定了就是我前端的问题,因为之前一直在做后端的错误排查, 以为是编译问题(因为之前也出现过这个问题) 好 , 我把其中一个参数类型改为String类型, …...

安全之护网(HVV)、红蓝对抗

文章目录 红蓝对抗什么是护网行动?护网分类护网的时间 什么是红蓝对抗红蓝对抗演练的目的什么是企业红蓝对抗红蓝对抗价值参考 红蓝对抗 什么是护网行动? 护网的定义是以国家组织组织事业单位、国企单位、名企单位等开展攻防两方的网络安全演习。进攻方…...

Leetcode 213 打家劫舍 II

题意理解: 你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果…...

【C语言】三子棋游戏实现代码

目录 1.三子棋代码功能介绍 2.三子棋游戏实现步骤 ①打印菜单栏 ②判断是否进入三子棋游戏 ③三子棋游戏基本函数实现 (1)清空(初始化)棋盘函数实现 (2)打印棋盘函数实现 (3&#xff0…...

docker常用10条容器操作命令

Docker 中一些常用的容器操作命令,我们可以根据需要使用这些命令来管理和操作 Docker 容器。我们这次以Hell-world这个镜像为例来说明: 1. docker pull hello-world #拉取hell-world镜像 2. docker images # 查看本地拉取的镜像 或者可以用 docker im…...

《MySQL 简易速速上手小册》第2章:数据库设计最佳实践(2024 最新版)

文章目录 2.1 规划高效的数据库架构2.1.1 基础知识2.1.2 重点案例:在线电商平台2.1.3 拓展案例 1:博客系统2.1.4 拓展案例 2:库存管理系统 2.2 数据类型和表设计2.2.1 基础知识2.2.2 重点案例:个人健康记录应用2.2.3 拓展案例 1&a…...

利用YOLOv8 pose estimation 进行 人的 头部等马赛克

文章大纲 马赛克几种OpenCV 实现马赛克的方法高斯模糊pose estimation 定位并模糊:三角形的外接圆与膨胀系数实现实现代码实现效果参考文献与学习路径之前写过一个文章记录,怎么对人进行目标检测后打码,但是人脸识别有个问题是,很多人的背影,或者侧面无法识别出来人脸,那…...

【Python 千题 —— 基础篇】查找年龄

Python 千题持续更新中 …… 脑图地址 👉:⭐https://twilight-fanyi.gitee.io/mind-map/Python千题.html⭐ 题目描述 题目描述 班级中有 Tom、Alan、Bob、Candy、Sandy 五个人,他们组成字典 {Tom: 23, Alan: 24, Bob: 21, Candy: 22, Sandy: 21},字典的键是姓名,字典的…...

前后端通讯:前端调用后端接口的五种方式,优劣势和场景

Hi,我是贝格前端工场,专注前端开发8年了,前端始终绕不开的一个话题就是如何和后端交换数据(通讯),本文先从最基础的通讯方式讲起。 一、什么是前后端通讯 前后端通讯(Frontend-Backend Commun…...

Mysql大表添加字段失败解决方案

背景 最近遇到一个问题,需要在user用户表千万级别数据中添加两个字段,发现老是加不上去,一直卡死。表数据量不仅大,而且是一个热点表,访问频率特别高,而且该表的访问是在一个大事务中。加字段的时候一直在…...

(52)只出现一次的数字III

文章目录 每日一言题目解题思路代码结语 每日一言 十年磨一剑,风雨未曾阻挡;愿你乘风破浪,不负韶华时光。 题目 题目链接:只出现一次的数字 给你一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现…...

Linux增删ip

Linux手动增删IP by: 铁乐猫 日期:2022.03.17 这里主要是记录手动临时添加和删除ip。 ifconfig方式 例,添加: ifconfig eth0:1 192.168.0.101/24移除 ifconfig eth0:1 downip addr方式 添加 ip addr add 192.168.0.102/24 dev eth0 …...

【计算机网络】时延,丢包,吞吐量(分组交换网络

时延 结点处理时延(nodal processing delay) dproc 排队时延(queuing delay) dqueue 传输时延(transmission delay) dtrans 路由器将分组推出所需要的时间,是分组长度和链路传输速率的函数 传播时…...

张楠辞任抖音集团CEO;东方甄选将开服饰号;小红书新增“附近”一级入口;华为分红770亿元

今日精选 • 张楠辞任抖音集团CEO,未来将聚焦剪映发展• 东方甄选将开服饰号 主打自营服饰• 小红书新增“附近”一级入口• 华为分红770亿元 大厂人事变动 • 上村健一出任中国U-16国家男子足球队主教练 投融资与企业动态 • 阿里大模型「通义千问」推出春节新…...

ES监控方法以及核心指标

文章目录 1. 监控指标采集1.1 部署elasticsearch_exporter1.2 prometheus采集elasticsearch_exporter的暴露指标1.3 promethues配置告警规则或者配置grafana大盘 2. 核心告警指标2.1 es核心指标2.2 es容量模型建议 3. 参考文章 探讨es的监控数据采集方式以及需要关注的核心指标…...

无人机应用场景和发展趋势,无人机技术的未来发展趋势分析

随着科技的不断发展,无人机技术也逐渐走进了人们的生活和工作中。无人机被广泛应用于很多领域,例如遥感、民用、军事等等。本文将围绕无人机技术的应用场景和发展趋势,从多角度展开分析。 无人机技术的应用场景 无人机在遥感方面的应用&…...

JavaGuide

JavaGuide(Java学习&面试指南) | JavaGuide JavaGuide 是一个面向 Java 开发者的知识整合平台,它提供了 Java 相关的学习资源、面试题、开发工具、框架和库等内容。JavaGuide 的目标是帮助 Java 开发者更好地学习和应用 Java 技术。 Ja…...

IDEA创建SpringBoot+Mybatis-Plus项目

IDEA创建SpringBootMybatis-Plus项目 一、配置Maven apache-maven-3.6.3的下载与安装(详细教程) 二、创建SpringBoot项目 在菜单栏选择File->new->project->Spring Initializr,然后修改Server URL为start.aliyun.com&#xff0c…...

第9章 SpringBoot综合项目实战——个人博客系统

学习目标 了解博客系统的系统功能和文件组织结构 熟悉博客系统数据库相关表及字段的设计 熟悉系统环境搭建的步骤及相关配置 掌握前后台管理模块功能的实现 掌握用户登录,定时邮件发送功能的实现 通过前面章节的学习,读者应该已经掌握了SpringBoot框架的基本知识,并学会了与…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 ​ 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...

云安全与网络安全:核心区别与协同作用解析

在数字化转型的浪潮中,云安全与网络安全作为信息安全的两大支柱,常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异,并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全:聚焦于保…...

LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》

🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...