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

C#中结构struct能否继承于一个类class,类class能否继承于一个struct

C#中结构struct能否继承于一个类class,类class能否继承于一个struct

答案是:都不能。

第一种情行,尝试结构继承类

报错:接口列表中的类型"XX"不是接口interface。

一般来说,都是结构只能实现接口,不能继承于类

如下代码片段:【尝试结构继承类】

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace DemoClassAndStruct
{class Program{static void Main(string[] args){Console.ReadLine();}}class TestClass  {public int Id;public string TestName { get; set; }}struct TestStruct : TestClass{public int TestId;public TestClass testClass { get; set; }}
}

我们发现,无法编译,报错:接口列表中的类型"XX"不是接口interface(或者说继承于一个接口)

第二种情形:尝试类继承结构

类class也不能继承于结构struct,错误信息:类无法从密封类型派生

如下代码片段:【尝试类继承结构】

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace DemoClassAndStruct
{class Program{static void Main(string[] args){Console.ReadLine();}}class TestClass : TestStruct{public int Id;public string TestName { get; set; }}struct TestStruct {public int TestId;public TestClass testClass { get; set; }}
}

仍然无法编译通过

在C#设计中,所有的结构stuct都特殊的认为是一种轻量型的密封类,密封类sealed是无法被继承的

比如常见的字符串String就是一个密封类

public sealed class String : IComparable, ICloneable, IConvertible, IEnumerable, IComparable<String>, IEnumerable<char>, IEquatable<String>

所谓继承,类似于一种从属关系【is-a】

我们提到继承(派生)都是说的是类class,也从来没听说过有结构可以继承的

比如,猫是一种动物,而动物就不一定是猫了

我们以结构 部分数组ArraySegment为例,我们发现结构只能实现接口,也不能继承于类

public struct ArraySegment<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IReadOnlyList<T>, IReadOnlyCollection<T>

同样,类也不能继承于结构,但类可以继承于其他非密封类,同时实现多个接口。

C#虽然是单继承【父类最多只有一个】,但可以实现多个接口,通过这样来伪装成多继承,实现多种复杂的业务逻辑

类class与结构struct互相不能继承的原因:

结构体是值类型,分配在栈stack上,内存是独占的,两个结构分配在不同的内存区域

篡改其中一个结构的值,并不能影响另一个结构的值。【结构是两条不同的河流】

基础数据类型int,double,DateTime都是结构 

而类是引用类型,所以类的资源是在堆heap上,两个类分配在相同的内存区域,

篡改其中一个类的值,导致另一个类的值自动篡改。【类是同一条河流】

string字符串虽然是类,但是编译器为了对字符串进行优化,处理逻辑反而和结构一样

如果结构可以继承类的话,相当于heap堆的东西复制到栈上,编译器就紊乱了,编译器纠结到底是不同的河流 还是 同一条河流。

同样类可以继承结构的话,相当于栈stack的东西复制到堆上,编译器一样也会紊乱,编译器纠结到底是不同的河流 还是 同一条河流。

类与结构使用场景

C#中的结构体通常是轻量级的数据类型,用于存储简单的值或者小的数据集合。而类则更适合表示复杂的对象或者具有丰富行为和状态的组件。这也是为什么结构体不适合被类继承的一个原因。

一般来说,当数据类型较小且需要频繁创建并传递时,例如表示坐标Coordinate或颜色Color等简单的值类型,使用结构体更加合适,因为它们可以被分配在栈上,速度更快,且不需要垃圾回收。此外,结构体具有内存对齐的特性,可以减少内存碎片和访问时间。

而当数据类型较大、有复杂的行为和状态,并且需要被多个对象共享时,使用类更加合适。类可以使用继承、多态和抽象等面向对象的特性,可以更好地组织和管理代码,实现高内聚低耦合的设计。

总的来说,如果需要表示简单的值类型并需要高效率地操作及传递数据,则使用结构体更加合适;如果需要表示复杂的对象并需要更加灵活的行为,则使用类更加合适。

是否可以继承关系如下图:(实现接口我们也认为是一种继承)

A继承于B类class【B】结构struct【B】接口interface【B】
类class【A】可以继承无法继承可以继承
结构struct【A】无法继承无法继承可以继承
接口interface【A】无法继承无法继承可以继承

类class作为结构struct的成员变量,结构struct作为类class的成员变量

同样,类对象可以作为结构的成员变量,结构的实例也可以作为类的成员变量,

结构对象 不能与null直接比较,如果结构对象与null比较,请使用可空类型

Nullable<TestStruct> 或者 TestStruct?

测试代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace DemoClassAndStruct
{class Program{static void Main(string[] args){TestStruct testStruct = new TestStruct();Console.WriteLine(testStruct.testClass == null);testStruct.Print();TestClass testClass = new TestClass();Console.WriteLine(testClass.testStruct.TestId);testClass.Print();Console.ReadLine();}}class TestClass {public int Id;public string TestName { get; set; }public TestStruct testStruct { get; set; }public void Print(){Console.WriteLine("这是测试类");}}struct TestStruct {public int TestId;public TestClass testClass { get; set; }public void Print() {Console.WriteLine("这是测试结构");}}
}

测试运行如图:

相关文章:

C#中结构struct能否继承于一个类class,类class能否继承于一个struct

C#中结构struct能否继承于一个类class&#xff0c;类class能否继承于一个struct 答案是&#xff1a;都不能。 第一种情行&#xff0c;尝试结构继承类 报错&#xff1a;接口列表中的类型"XX"不是接口interface。 一般来说&#xff0c;都是结构只能实现接口&#x…...

【Vulhub】Fastjson 1.2.24_rce复现

文章目录 一&#xff0c;Fastjson是什么&#xff1f;二&#xff0c;fastjson漏洞原理三&#xff0c;判断是否有fastjson反序列化四&#xff0c;复现Fastjson 1.2.24_rce(vulhub)环境配置1.判断是否存在Fastjson反序列化2.反弹shell3.启动RMI服务器4.构造恶意POST请求 一&#x…...

【iconv】UTF-8字符串转换为UTF-16字符串

使用<iconv.h>来进行字符串编码的转换 #include <iconv.h> #include <iostream> #include <string.h> #include <unistd.h> #include <memory> #include <fcntl.h>// 需要链接iconv库// iconv -l 命令可列出所有支持的格式 // exam…...

AI技术的未来展望:重塑人类社会的智能革命

一、引言 随着技术的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经不再是科幻小说中的概念&#xff0c;而是成为了我们生活中不可或缺的一部分。从简单的智能助手到复杂的自动化生产线&#xff0c;AI技术正在以前所未有的速度改变着世界。本文将对AI技术的未来…...

掘金AI 商战宝典-系统班:2024掘金AIGC课程(30节视频课)

课程目录 1-第一讲学会向Al提问&#xff1a;万能提问公式_1.mp4 2-第二讲用AI写视频脚本_1.mp4 3-第三讲用AI写视频口播文案_1.mp4 4-第四讲用AI自动做视频&#xff08;上&#xff09;_1.mp4 5-第五讲用AI自动做视频&#xff08;中&#xff09;_1.mp4 6-第六讲用AI自动做视…...

C# WinForm —— 26 ImageList 介绍

1. 简介 图片集合&#xff0c;用于存储图像的资源&#xff0c;并在关联控件中显示出来 可以通过 索引、键名 访问每张图片 没有事件 2. 属性 属性解释(Name)控件ID&#xff0c;在代码里引用的时候会用到,一般以 imgList 开头ClolorDepth用于呈现图像的颜色数&#xff0c;默…...

Vue:现代前端开发的首选框架-【声明周期钩子详解】

引言 Vue.js 是一个流行的前端框架&#xff0c;它通过组件化的开发方式&#xff0c;让开发者能够构建出高效且可维护的应用程序。在Vue中&#xff0c;生命周期钩子&#xff08;Lifecycle Hooks&#xff09;是理解组件行为的关键概念。本文将深入探讨Vue生命周期钩子&#xff0…...

【因果推断python】8_线性回归模型2

目录 回归理论 非随机数据的回归 回归理论 我不打算深入研究线性回归是如何构建和估计的。然而&#xff0c;一点点理论将有助于解释它在因果推断中的力量。首先&#xff0c;回归解决了理论上的最佳线性预测问题。令 是一个参数向量&#xff1a; 线性回归找到最小化均方误差 (…...

MySQL目录和文件

MySQL目录和文件 bin目录 存储一些mysql脚本比如mysqld、mysqld-self等等&#xff0c;用于执行mysql一些操作 数据目录 show variables like datadir;--查看数据目录位置每一个数据库都有一个和数据库名相同的文件夹&#xff1b;MySQL5.7开始每创建一个表&#xff0c;在Innod…...

0基础学习Elasticsearch-Quick start

文章目录 1 背景2 前言3 快速部署ES4 快速部署Kibana5 发送请求给ES5.1 打开Kibana控制台5.2 通过REST API发送请求5.3 通过curl发送请求5.4 添加数据5.4.1 添加单个document5.4.2 添加多个document 5.5 搜索数据5.5.1 搜索所有documents5.5.2 match查询 6 总结 1 背景 因电商项…...

Centos给普通用户添加sudo命令权限

打开sudoers文件 sudo visudo 修改sudoers文件 找到root ALL(ALL) ALL这一行&#xff0c;即如下图标出红线的一行 在此行下新增如下内容: lbs为用给予sudo执行权限的用户名 # 执行sudo命令&#xff0c;需要输入命令 lbs ALL(ALL) ALL 或 # 执行sudo命令&#xff0c;…...

编写备份MySQL 脚本

目录 环境准备 增量备份 增量备份和差异备份 完整代码如下 测试脚本是否正常 星期天运行脚本&#xff08;完全备份&#xff09; 星期一运备份脚本&#xff08;增量备份&#xff09; 星期二备份数据&#xff08;其他天--增量备份&#xff09; 星期三备份数据&#xff08;差异备…...

C语言中的数据类型转换:隐式类型转换与显示类型转换

一. 简介 本文简单学习一下&#xff0c;C语言中的数据类型转换。重点学习一下隐式类型转换。 二. C语言中的数据类型转换&#xff1a;隐式类型转换与显示类型转换 类型转换&#xff08;TypeCasting&#xff09;&#xff1a;在C语言中是将一种数据类型值转换为另一种数据类型…...

Android 安卓通过bindService ServiceConnection 没有响应的问题

bindService 失败且 ServiceConnection 没有响应可能由多种原因造成。以下是一些可能的原因和相应的解决方法&#xff1a; Service未正确声明或注册&#xff1a; 如果Service没有在AndroidManifest.xml文件中正确声明或注册&#xff0c;bindService将会失败。解决方法&#xf…...

python切片(彻底解除对切片的曲解)

sequence[start:stop:step] **start: **step为正时默认为0,step为负时默认为-1 stop:_ step为正时默认为结尾结束,step为负时默认为开始位置_ ss=“abcdefg” 以该字符串举例,ss[start:stop:step]的意思是将字符串ss从start开始截取(包括start),截取到stop(不包括sto…...

Java—— StringBuilder 和 StringBuffer

1.介绍 由于String的不可更改特性&#xff0c;为了方便字符串的修改&#xff0c;Java中又提供了StringBuilder和Stringbuffer类&#xff0c;这两个类大部分功能是相同的&#xff0c;以下为常用方法&#xff1a; public static void main(String[] args) {StringBuilder sb1 n…...

vs2019 c++20 规范 STL库中关于时间的模板

在学习线程的时候&#xff0c;一些函数会让线程等待或睡眠一段时间。函数形参是时间单位&#xff0c;那么在 c 中是如何记录和表示时间的呢&#xff1f;以下给出模板简图&#xff1a; 谢谢...

激光焊接机作为一种高效、精密的焊接设备

激光焊接机是一种用于材料加工时激光焊接的机器&#xff0c;以下是对其的详细介绍&#xff1a; 1. 定义与别称&#xff1a; 激光焊接机&#xff0c;又常称为激光焊机、镭射焊机&#xff0c;是材料加工激光焊接时用的机器。 2. 工作原理&#xff1a; 激光焊接是利用高能量…...

vite为什么速度快

原因 vite快的原因是因为 vite在开发环境中是使用的 esbuild&#xff0c;esbuild 是 go 写的&#xff0c;go 编译型语言、多线程&#xff0c;nodejs 解释型语言、单线程&#xff0c;并且 vite 使用了原生 esm 导入的&#xff0c;所以快一点&#xff0c;当然&#xff0c;这也…...

Java网络编程(下)

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f649; 内容推荐:Java网络编程&#x1f649; &#x1f439;今日诗词:姑苏城外寒山寺&#xff0c;夜半钟声到客船&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

nnUNet V2修改网络——暴力替换网络为UNet++

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...

嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)

目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 ​编辑​编辑 UDP的特征 socke函数 bind函数 recvfrom函数&#xff08;接收函数&#xff09; sendto函数&#xff08;发送函数&#xff09; 五、网络编程之 UDP 用…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...

鸿蒙HarmonyOS 5军旗小游戏实现指南

1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;采用DevEco Studio实现&#xff0c;包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...