C#教程 - 结构类型(Struct Type)
2022/9/16 1:18:32
本文主要是介绍C#教程 - 结构类型(Struct Type),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
更新记录
转载请注明出处:https://www.cnblogs.com/cqpanda/p/16675933.html
2022年9月15日 发布。
2022年9月10日 从笔记迁移到博客。
结构类型(Struct Type)说明
提供类似类的一种逻辑结构,是一种用户自定义的值类型,可以包含数值和方法
结构是值类型,不可以赋值为null
结构传参按 值传递
结构自带默认无参构造函数并且不可以删除
结构禁止字段成员声明时初始化
自定义结构的构造函数必须初始化所有成员
结构没有析构函数,但可以自定义实现IDisponse
结构是sealed,不可以派生
结构也可以是泛型的
结构可以实现接口
结构也支持分部结构
结构继承自System.ValueType,而System.ValueType继承自System.Object
预定义基础类型在.NET库中本质上都是定义为结构类型
结构与类对比
相同:结构 和 类 都具有 数据 和 函数成员
区别:
Class是引用类型,Struct是值类型
结构是隐式密封的,不可以派生(隐式集成自System.Object和System.ValueType)
Struct使用自定义的构造函数后,系统自带的构造函数不会消失
struct不支持带参数的构造函数(parameterless constructor)、析构函数(finalizer)
在声明结构的时候进行不可以对字段赋值
struct不支持属性初始化器(field initializers)
struct不支持虚成员或保护字段(virtual or protected members)
一般情况下,结构的实例消耗小,使用结构可以提高一些性能,但是装箱和拆箱的消耗也不低,需要权衡考虑
尽量少或者最好不要在结构中定义方法,只让结构保存数据成员,用于管理数据集
结构可以包含类可以包含的所有成员,但以下成员除外:
无参数的构造函数(A parameterless constructor)
字段初始化(Field initializers)
析构器(A finalizer)
虚成员或保护成员(Virtual or protected members)
声明结构类型
struct Panda { }
注意:结构中的字段不可以直接定义时初始化
注意:结构类型中的成员不可以使用以下修饰符:
protected、internal、virtual、abstract
实例:声明结构的错误示例
public struct Point { int x = 1; // Illegal: field initializer int y; public Point() { } // Illegal: parameterless constructor public Point(int x) { this.x = x; } // Illegal: must assign field y }
只读 与 结构
说明
注意:除非必要,否则尽量不要将值类型定义为不可变
只读结构(Read-only Structs)
只读结构内部所有的字段都只能是只读的,可以防止字段被修改
注意:从C# 7.2可用
注意:从C# 8开始支持只读方法
实例:只读结构内的只读字段
readonly struct Point { //只读字段成员 public readonly int _X; public readonly int _Y; public Point(int x, int y) { this._X = x; this._Y = y; } }
实例:结构内的只读方法
struct Point { public int X; public int Y; public Point(int x, int y) { this.X = x; this.Y = y; } //只读方法 public readonly void ResetX() { Console.WriteLine("Panda666"); } }
实例:可以给结构体内的方法定义为readonly,这样该方法就不可以修改成员
struct Point { public int X, Y; public readonly void ResetX() => X = 0; // Error! }
注意:如果readonly函数调用非readonly函数,编译器将生成警告
只读属性成员
从C# 6.0开始支持结构内定义只读属性
实例:
public struct PandaStruct { //只读属性成员 public string Property1 { get; } public string Property2 { get; } public PandaStruct(string arg1, string arg2) { this.Property1 = arg1; this.Property2 = arg2; } }
引用结构(Ref Structs)
使用ref关键字修饰struct后,struct只能分配在栈上
注意:从C# 7.2 开始可用
常见使用场景:
配合e Span
实例:ref struct分配到堆上,出现错误
ref struct Point { public int X, Y; } class MyClass { Point P; } // Error: will not compile! 作为类的成员,将分配在堆上 var points = new Point [100]; // Error: will not compile! 作为数组的类型,数组分配在堆上
实例:可以用ref struct的地方和不可以用的地方
using System; using System.Text.Json; namespace ConsoleApp2 { /// <summary> /// 定义引用结构体 /// </summary> public ref struct PandaStruct { public string Code{ get; set; } public string Title { get; set; } } public class PandaClass { //定义成员 public PandaStruct E; //error,不可以这样 } class Program { static void Main(string[] args) { //这样是可以的 PandaStruct pandaStruct = new PandaStruct(); //wait Console.ReadKey(); } } }
结构赋值
结构是值类型,所以一般存储在栈上
结构与结构之间赋值是复制的内容,而类之间的赋值时复制的引用
构造函数与析构函数
结构可以有构造函数,但是不可以有析构函数
结构默认自带一个无参数的构造函数,并且该构造函数不可以删除和自定义
但可以自定义其他构造函数
结构的构造函数可以是静态的
实例化结构
实例化结构可以使用new或者不使用new
不使用new的话,需要把每个字段都赋值之后才可以使用其函数成员
using System; namespace Test { struct Panda { private int _x; private int _y; public Panda(int x, int y) { this._x = x; this._y = y; } } class Program { static void Main() { Panda s = new Panda(1, 2); Console.ReadKey(); } } }
实例:实例化结构默认值
struct PandaStruct { } PandaStruct pandaStruct = default;
数据成员默认初始化的默认值
Unlike with instance fields
if no initialization for a static field is provided
the static field will automatically be assigned its default value (0, null, false, and so on)—the equivalent of default(T)
结构装箱和拆箱
装箱(boxing):将 值类型 包装为 引用类型
拆箱(unboxing):将 引用类型 中的数据转为 值类型
结构作为返回值和参数
作为返回值:返回的是结构实例的值副本
作为值参数:使用的是实参的值副本
ref和out参数:结构作为ref或out参数,传入的参数是结构实例的别名
泛型结构
struct Panda<T> { public Panda(T code) { this.Code = code; } public T Code { get; set; } }
结构最佳实践
除非结构在逻辑上表示单个值,占用16个字节或更少的存储空间
不可变且不经常装箱,否则请勿定义结构
这篇关于C#教程 - 结构类型(Struct Type)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-11-18微软研究:RAG系统的四个层次提升理解与回答能力
- 2024-11-15C#中怎么从PEM格式的证书中提取公钥?-icode9专业技术文章分享
- 2024-11-14云架构设计——如何用diagrams.net绘制专业的AWS架构图?
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#
- 2024-01-24Advanced .Net Debugging 1:你必须知道的调试工具