c# 结构体(Struct)与枚举(Enum)与记录(Record)

 结构体(Struct)

struct是值类型数据,存储在栈上,原来的值数据一般一般存储单一数据结构定义的数据是记录(存储的数据多).

类也可以存储大量数据,但是类是引用结构,存储在堆上.严谨来说,引用类型的值存储在堆上,引用类型的存储地址存储在栈上.

struct的数据成员不能通过初始化器来进行初始化.

值类型的特点:将一个变量赋值给另一个变量,修改两个变量,不会相互影响,

栈的特点:1.先进后出(FILO)结构.2.栈在分配空间是有顺序的,先声明变量先分配空间,分配顺序是从下向上;堆的特点,托管堆(有管理的堆,代码安全,gc垃圾回收),堆是树形结构,在分配空间时没有顺序可言,堆在运行期间分配空间.

Struct和Class区别?

  • struct 是值类型,class 是对象类型
  • struct 不能被继承,class 可以被继承
  • struct 默认的访问权限是public,而class 默认的访问权限是private.
  • struct总是有默认的构造函数,即使是重载默认构造函数仍然会保留。这是因为struct的构造函数是由编译器自动生成的,但是如果重载构造函数,必需对struct中的变量全部初始化。并且struct的用途是那些描述轻量级的对象,例如Line,Point等,并且效率比较高。class在没有重载构造函数时有默认的无参数构造函数,但是一被重载,默认构造函数将被覆盖。
  • struct的new和class的new是不同的。struct的new就是执行一下构造函数创建一个新实例再对所有的字段进行Copy。而class则是在堆上分配一块内存然后再执行构造函数,struct的内存并不是在new的时候分配的,而是在定义的时候分配

枚举(Enum)

枚举类型 是由基础整型数值类型的一组命名常量定义的值类型。 若要定义枚举类型,请使用 enum 关键字并指定枚举成员 的名称:

enum Season
{
    Spring,
    Summer,
    Autumn,
    Winter
}

默认情况下,枚举成员的关联常数值为类型 int;它们从零开始,并按定义文本顺序递增 1。 可以显式指定任何其他整数数值类型作为枚举类型的基础类型。 还可以显式指定关联的常数值,如下面的示例所示:

enum ErrorCode : ushort
{
    None = 0,
    Unknown = 1,
    ConnectionLost = 100,
    OutlierReading = 200
}

不能在枚举类型的定义内定义方法。 若要向枚举类型添加功能,请创建扩展方法

枚举类型 E 的默认值是由表达式 (E)0 生成的值,即使零没有相应的枚举成员也是如此。

可以使用枚举类型,通过一组互斥值或选项组合来表示选项。 若要表示选项组合,请将枚举类型定义为位标志。

对于任何枚举类型,枚举类型与其基础整型类型之间存在显式转换。 如果将枚举值转换为其基础类型,则结果为枚举成员的关联整数值。

public enum Season
{
    Spring,
    Summer,
    Autumn,
    Winter
}

public class EnumConversionExample
{
    public static void Main()
    {
        Season a = Season.Autumn;
        Console.WriteLine($"Integral value of {a} is {(int)a}");  // output: Integral value of Autumn is 2

        var b = (Season)1;
        Console.WriteLine(b);  // output: Summer

        var c = (Season)4;
        Console.WriteLine(c);  // output: 4
    }
}

使用 Enum.IsDefined 方法来确定枚举类型是否包含具有特定关联值的枚举成员。

对于任何枚举类型,都存在分别与 System.Enum 类型的装箱和取消装箱相互转换。

记录(Record)

record类型是一种用record关键字声明的新的引用类型,与类不同的是,它是基于值相等而不是唯一的标识符——对象引用。他有着引用类型的支持大对象、继承、多态等特性,也有着结构的基于值相等的特性。可以说有着class和struct两者的优势,在一些情况下可以用以替代class和struct。

提到不可变的类型,我们会想到readonly struct,那么为什么要选择添加一个新的类型,而不是用readonly struct呢?这是因为记录有着如下优点:

  • 在构造不可变的数据结构时,它的语法简单易用。

  • record为引用类型,不用像值类型在传递时需要内存分配,并进行整体拷贝。

  • 构造函数和结构函数为一体的、简化的位置记录

  • 有力的相等性支持 —— 重写了Equals(object), IEquatable, 和GetHashCode()这些基本方法。

记录(record)和类一样,在面向对象方面,支持继承,多态等所有特性。除过前面提到的record专有的特性,其他语法写法跟类也是一样。同其他类型一样,record的基类依然是object。
要注意的是:

  • 记录只能从记录继承,不能从类继承,也不能被任何类继承。

  • record不能定义为static的,但是可以有static成员。

当你看到record或者record修饰的record struct、record class时,记住如下区别:

声明和实例化类或结构时使用的语法与操作记录时的相同。 只是将 class 关键字替换为 record,或者使用 record struct 而不是 struct。 同样地,记录类支持相同的表示继承关系的语法。 记录与类的区别如下所示:

可在主构造函数中使用位置参数来创建和实例化具有不可变属性的类型。
在类中指示引用相等性或不相等的方法和运算符(例如 Object.Equals(Object) 和 ==)在记录中指示值相等性或不相等。
可使用 with 表达式对不可变对象创建在所选属性中具有新值的副本。
记录的 ToString 方法会创建一个格式字符串,它显示对象的类型名称及其所有公共属性的名称和值。
记录可从另一个记录继承。 但记录不可从类继承,类也不可从记录继承。
记录结构与结构的不同之处是,编译器合成了方法来确定相等性和 ToString。 编译器为位置记录结构合成 Deconstruct 方法。

编译器为 record class 中的每个主构造函数参数合成一个公共仅初始化属性。 在 record struct 中,编译器合成公共读写属性。 编译器不会在不包含 record 修饰符的 class 和 struct 类型中创建主构造函数参数的属性。

  • 9
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玉玊则不达

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值