ToB企服应用市场:ToB评测及商务社交产业平台
标题:
.NET 结构体
[打印本页]
作者:
小秦哥
时间:
2024-12-27 19:11
标题:
.NET 结构体
我们都知道结构体struct,在大量创建、引用的场景下相比类class能提升很大性能。本文介绍下如何正确使用struct
struct定义
1 struct Point
2 {
3 public float X;
4 public float Y;
5 }
6
7 class Rect
8 {
9 public Point Position;
10 }
11
12 Rect rect = new Rect();
复制代码
上述代码中,rect的Position字段并没有分配到栈上,反而是和Rect的实例一起被分配到了托管堆中。除此之外,装箱也会导致结构体实例分配到托管堆:
1 Point point = new Point();
2 object obj = point; // 装箱,结构体转移到托管堆
复制代码
所以假如由于性能要求或者别的原因想限定struct只分配到栈上的话,可以添加ref:
1 ref struct Point
2 {
3 public float X;
4 public float Y;
5 }
复制代码
这种情况下,struct关键字前添加ref是指将结构体声明为只能在栈上分配的结构体,对于这种结构体,任何大概将其转移到托管堆的行为都将被制止(比方在引用类型中定义ref结构体字段,或者进行装箱操作):
1 class Rect
2 {
3 public Point Position; // 错误,Position会随着Rect实例转移到托管堆
4 }
5
6 Point point = new Point();
7 object obj = point; // 错误,point会被装箱到托管堆
复制代码
别的,ref声明的struct可以继续作为字段在新struct内声明:
1 ref struct PointNew
2 {
3 public Point Point; // 允许,因为XPoint同样保证了栈上分配
4 }
复制代码
还可以声明只读的ref结构体:
1 readonly ref struct PointNew
2 {
3 public Point Point; // 允许,因为XPoint同样保证了栈上分配
4 }
复制代码
使用struct
1. 结构体作为参数传递
1 Point p = new Point();
2 TestAdd(ref p);
3
4 void TestAdd(ref Point point)
5 {
6 point.X += 1;
7 }
复制代码
假如不是只传值而是需要变更数据,需要添加ref,否则TestAdd中point只会作为原来p的副本天生一个新结构体。那最终p中的X值还是初始值0。ref我们都熟悉了,值类型假如作为参数输入后,外部同步修改也是使用ref
2. 结构体存储大小
看下面这段代码,输出结构体在栈上所需的内存大小:
1 [StructLayout(LayoutKind.Auto)]
2 struct TestStorage
3 {
4 public byte A;
5 public int B;
6 public byte C;
7 public byte D;
8 public byte E;
9 }
10 // 输出
11 unsafe
12 {
13 Debug.WriteLine(sizeof(TestStorage));
14 }
复制代码
上面输出的值是12。我们聊下内存布局:
1)Sequential:顺序布局,按字段的声明顺序布局,是默认行为
2)Auto:自动布局,自动分列字段顺序以用最小的空间来储存字段
3)Explicit:显式布局,手动指定字段地址的偏移
一般来说,byte是1,int是4。
在不添加[StructLayout(LayoutKind.Auto)]标记时,由于需要内存对齐,字段B是4,那内存大小就需要以4+4+4=12来分配,前面4存储字段A 1的内存,后面4存储字段CDE一共3的内存大小
添加[StructLayout(LayoutKind.Auto)]后,内存对齐,只需要4+4=8的内存大小
我们使用Struct场景主要有以下使用场景:
一般是某类数据使用较多、有较大的内存题目 - 对于不需要频繁分配和释放的大量小对象,可以使用结构体减少堆内存的压力
现有类对象创建采取过于频繁,性能有较大损耗 - 可以使用结构体,减少对象创建、垃圾采取的开销
结构体适合用于封装简单的数据,比方坐标点(Point)、复数(Complex Number)、时间段(TimeSpan)等
参考文章:
结构类型 - C# reference | Microsoft Learn
Struct 和 Class 的区别以及使用场景_struct和class使用场景-CSDN博客
出处:
http://www.cnblogs.com/kybs0/
让学习成为习惯,假设明天就有巨大机会等着你,你准备好了么本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保存追究法律责任的权利。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4