C# struct

很困惑,为什么C#会有struct 这样一个关键字。虽然我用C#几年了,但绝少用到此关键字。我在相关书籍上学习C#的时候,看到过struct内容——但C#并不是我的第一入门语言,所以没有那么细致的学习。这其中也有一部分原因是有些书籍会淡化struct,更在的原因则在于我的先验经验上。忽略struct关键字的理由如下:

  1. 已经有class了,还有struct干啥?节约内存?这不是C#的主要卖点吧。
  2. 各种神奇的限制。既然如此,就更不想用了。
  3. 难道只是为了与C++、win32的互操作?现在应用越来越远离OS,场景也难得碰到,还是不用吧。

大概如此想法吧。最近当做面试官,面试了一些应聘者,另一C++出生的哥们,问到了struct与class的区别——甚至内存布局,一想到自己也不甚清楚,还是了解一下吧。C++出身的人,总是不忘内存。

在MSDN上找到关于struct的相关信息:strcut是值类型,而class是引用类型。struct在赋值时,是拷贝操作。而引用类型,只是引用了同一内容。值类型类似C语言中的函数形参,而引用类型类似实参。还拥有值类型的一些其他特征,比如可空(Nullable),等等。

使用上还有其他一些特征与限制[1],但我更想知道为什么要有struct。

  1. 可以自定义新的值类型。一般值类型只有原始基本类型,比如int, byte。
  2. 结构最适合一些小型数据结构,这些数据结构包含的数据以创建结构后不修改的数据为主。[2]
  3. 结构更加有效,也就是更加节省内存, 提升处理效率[3]。因为没有class的很多特性,所以也没有class的元数据块。
  4. 结构是值类型,而值类型是可计算的,拥有可计算的语义。例如DataTime。[4]

从以上内容可以看出使用struct的一般场景:

  1. 自定义的类型语义上为值类型。稳定不变的,可计算的。
  2. 需要更高效率的场景。

关于上述第二点,记得其失去了面向对象很多特性。

[1] 结构(C#编程指南), https://msdn.microsoft.com/zh-cn/library/saxz13w4(v=vs.90).aspx

[2] 类和结构(C#编程), https://msdn.microsoft.com/zh-cn/library/ms173109.aspx

[3] 使用结构(C#编程指南), https://msdn.microsoft.com/zh-cn/library/0taef578.aspx

[4] 深入理解C#,人民邮电出版社, p41-43

时间: 2024-10-12 12:53:43

C# struct的相关文章

struct&&class 空的大小

#include using namespace std; class ClassA { }; class ClassB { private: int b; }; class ClassC : public ClassA { }; class ClassD : public ClassB { }; class ClassE { public: int GetReturnValue() { return 0; } }; struct StructA { }; int main() { cout <

struct iphdr中的__LITTLE_ENDIAN_BITFIELD和__BIG_ENDIAN_BITFIELD

__LITTLE_ENDIAN_BITFIELD表示小端序,__BIG_ENDIAN_BITFIELD表示大端序. /usr/include/linux/ip.h中有一段代码定义了ip首部的结构体,如下: struct iphdr { #if defined(__LITTLE_ENDIAN_BITFIELD) __u8 ihl:4, version:4; #elif defined (__BIG_ENDIAN_BITFIELD) __u8 version:4, ihl:4; #else #err

GO语言struct语法

struct -使用type<Name>struct{}定义结构,名称遵循可见性规则 -支持指向自身的指针类型成员 -支持匿名结构.可作用成员或定义成员变量 -匿名结构也可以用于MAP的值 -可以使用字面值对结构进行初始化 -允许值通过指针来读写结构成员 -相同类型的成员可进行直接拷贝赋值 -支持==与!=比较运算符,不支持>或< -支持匿名字段,本质上是定义了以某个类型名称的字段 -嵌入结构作为匿名字段看起来像继承.但不是继承 -可以使用匿名字段的指针 package main

Python学习笔记(三十五)struct

摘抄自:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431955007656a66f831e208e4c189b8a9e9f3f25ba53000 Python提供了一个struct模块来解决bytes和其他二进制数据类型的转换. struct的pack函数把任意数据类型变成bytes: >>> import struct >>> struc

C++中sizeof(struct)怎么计算?(转)

struct为空时,大小为1. 1. sizeof应用在结构上的情况 请看下面的结构: 1 struct MyStruct 2 { 3 double dda1; 4 char dda; 5 int type; 6 }; 对结构MyStruct采用sizeof会出现什么结果呢?sizeof(MyStruct)为多少呢?也许你会这样求: sizeof(MyStruct)=sizeof(double) sizeof(char) sizeof(int)=13 但是当在VC中测试上面结构的大小时,你会发现

P Invoke struct结构

一.获取Struct CHCNetSDK.NET_DVR_PTZPOS pos = new CameraTest.CHCNetSDK.NET_DVR_PTZPOS(); int size = Marshal.SizeOf(typeof(CHCNetSDK.NET_DVR_PTZPOS)); IntPtr ptr = Marshal.AllocHGlobal(size);// 申请内存 uint bytesReturnd = 0; try { if (!CHCNetSDK.NET_DVR_GetD

消息队列状态:struct msqid_ds

Linux的消息队列(queue)实质上是一个链表, 它有消息队列标识符(queue ID). msgget创建一个新队列或打开一个存在的队列; msgsnd向队列末端添加一条新消息; msgrcv从队列中取消息, 取消息是不一定遵循先进先出的, 也可以按消息的类型字段取消息. 1. 标识符(des)和键(key): 消息队列, 信号量和共享存储段, 都属于内核中的IPC结构, 它们都用标识符来描述. 这个标识符是一个非负整数, 与文件描述符不同的是, 创建时并不会重复利用通过删除回收的整数,

c语言struct和c++的class的暧昧

c语言风格的封装 数据放在一起,以引用和指针的方式传给行为c++ 认为封装不彻底 1数据和行为分开 对外提供接口 2没有权限设置 看看struct的一个例子 1 //data.h 2 3 //c语言风格的封装 数据放在一起,以引用和指针的方式传给行为 4 //c++ 认为封装不彻底 5 //1数据和行为分开 对外提供接口 6 //2没有权限设置 7 8 struct Date 9 { 10 int year; 11 int month; 12 int day; 13 }; 14 15 16 vo

python中的struct

我们知道python只定义了6种数据类型,字符串,整数,浮点数,列表,元组,字典.但是C语言中有些字节型的变量,在python中该如何实现呢?这点颇为重要,特别是要在网络上进行数据传输的话. python提供了一个struct模块来提供转换.下面就介绍这个模块中的几个方法. struct模块中最重要的三个函数是pack(), unpack(), calcsize() # 按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流) pack(fmt,v1, v2, ...) #

C 语言Struct 实现运行类型识别 RTTI

通过RTTI,能够通过基类的指针或引用来检索其所指对象的实际类型.c++通过下面两个操作符提供RTTI. (1)typeid:返回指针或引用所指对象的实际类型. (2)dynamic_cast:将基类类型的指针或引用安全的转换为派生类型的指针或引用. 对于带虚函数的类,在运行时执行RTTI操作符,返回动态类型信息:对于其他类型,在编译时执行RTTI,返回静态类型信息. 当具有基类的指针或引用,但需要执行派生类操作时,需要动态的强制类型转换(dynamic_cast).这种机制的使用容易出错,最好