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

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

答案是:都不能。

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

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

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

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

cs 复制代码
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,错误信息:类无法从密封类型派生

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

cs 复制代码
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就是一个密封类

cs 复制代码
public sealed class String : IComparable, ICloneable, IConvertible, IEnumerable, IComparable<String>, IEnumerable<char>, IEquatable<String>

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

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

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

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

cs 复制代码
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?

测试代码:

cs 复制代码
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("这是测试结构");
        }
    }
}

测试运行如图:

相关推荐
陈皮话梅糖@1 小时前
使用 Provider 和 GetX 实现 Flutter 局部刷新的几个示例
开发语言·javascript·flutter
简简单单做算法1 小时前
基于mediapipe深度学习和限定半径最近邻分类树算法的人体摔倒检测系统python源码
人工智能·python·深度学习·算法·分类·mediapipe·限定半径最近邻分类树
hvinsion2 小时前
基于PyQt5的自动化任务管理软件:高效、智能的任务调度与执行管理
开发语言·python·自动化·自动化任务管理
Tisfy2 小时前
LeetCode 2360.图中的最长环:一步一打卡(不撞南墙不回头) - 通过故事讲道理
算法·leetcode··题解
Aphelios3802 小时前
Java全栈面试宝典:线程机制与Spring IOC容器深度解析
java·开发语言·jvm·学习·rbac
LuckyAnJo2 小时前
Leetcode-100 链表常见操作
算法·leetcode·链表
qq_529835353 小时前
装饰器模式:如何用Java打扮一个对象?
java·开发语言·装饰器模式
日暮南城故里3 小时前
Java学习------源码解析之StringBuilder
java·开发语言·学习·源码
Vitalia3 小时前
从零开始学Rust:枚举(enum)与模式匹配核心机制
开发语言·后端·rust
双叶8364 小时前
(C语言)虚数运算(结构体教程)(指针解法)(C语言教程)
c语言·开发语言·数据结构·c++·算法·microsoft