.jpg)
什么时候应该在 C# 中使用结构而不是类?我的概念模型是,当项目只是值类型的集合时,使用结构。一种在逻辑上将它们结合在一起形成一个有凝聚力的整体的方法。
我在这里遇到了这些规则:
这些规则有效吗?结构在语义上是什么意思?

网友回答:
每当您:
然而,需要注意的是,结构体(任意大)比类引用(通常是一个机器字)更昂贵,因此类在实践中可能会更快。

网友回答:
OP引用的消息来源具有一定的可信度…但是微软呢——对结构使用的立场是什么?我向微软寻求一些额外的学习,这是我的发现:
如果
类型的实例很小且通常生存期较短或通常嵌入到其他对象中
,请考虑定义结构而不是类。除非类型具有以下所有特征,否则不要定义结构:
- 它在逻辑上表示单个值,类似于基元类型(整数、双精度等)。
- 它的实例大小小于 16 字节。
- 它是不可变的。
- 它不必经常装箱。
好的,无论如何#2和#3。我们心爱的词典有 2 个内部结构:
[StructLayout(LayoutKind.Sequential)] // default for structs
private struct Entry //<Tkey, TValue>
{
// View code at *Reference Source
}
[Serializable, StructLayout(LayoutKind.Sequential)]
public struct Enumerator :
IEnumerator<KeyValuePair<TKey, TValue>>, IDisposable,
IDictionaryEnumerator, IEnumerator
{
// View code at *Reference Source
}
*参考资料来源
“JonnyCantCode.com”来源得到了 3 分中的 4 分——这是可以原谅的,因为 #4 可能不是问题。如果您发现自己在装箱结构,请重新考虑您的架构。
让我们看看为什么微软会使用这些结构:
EntryEnumeratorEntry永远不会作为参数传递到字典类之外。进一步的调查表明,为了满足IEnumerable的实现,字典使用每次请求枚举器时复制的结构…意义。EnumeratorEnumerator更新 – 此外,请注意,当结构实现接口(如枚举器所做的那样)并强制转换为该实现的类型时,该结构将成为引用类型并移动到堆中。在字典类内部,枚举器仍然是值类型。但是,一旦方法调用 ,就会返回引用类型。GetEnumerator()IEnumerator
我们在这里看不到的是保持结构不可变或保持实例大小仅为 16 字节或更小的任何尝试或证明:
readonlyEntry具有不确定的生存期(从 、 到 、 或垃圾回收);Add()Remove()Clear()和。。。
4.两种结构都存储了TKey和TValue,我们都知道它们非常有能力成为参考类型(添加奖励信息)
尽管有哈希键,但字典速度很快,部分原因是实例化结构比引用类型更快。在这里,我有一个存储 300,000 个随机整数和顺序递增键。Dictionary<int, int>
容量:312874
内存大小:2660827字节
完成调整大小:5ms 总填充时间:889ms
容量:在必须调整内部数组大小之前可用的元素数。
MemSize:通过将字典序列化为 MemoryStream 并获取字节长度(对于我们的目的来说足够精确)来确定。
已完成调整大小:将内部数组的大小从150862元素调整为312874元素所需的时间。当您认为每个元素都是通过 按顺序复制的时,这并不太破旧。Array.CopyTo()
填充总时间:由于日志记录和我添加到源的事件,不可否认地存在偏差;但是,在操作过程中调整大小 300 次时填充 15k 整数仍然令人印象深刻。只是出于好奇,如果我已经知道容量,那么要填补的总时间是多少?13毫秒OnResize
那么,现在,如果是一个班级呢?这些时间或指标真的会有那么大的差异吗?Entry
容量:312874
内存大小:2660827字节
完成调整大小:26ms 总填充时间:964ms
显然,最大的区别在于调整大小。如果使用容量初始化字典有什么区别?不够关心…12毫秒。
发生的情况是,因为它是一个结构,所以它不需要像引用类型那样初始化。这既是价值类型的美丽,也是价值类型的祸根。为了用作引用类型,我必须插入以下代码:EntryEntry
/*
* Added to satisfy initialization of entry elements --
* this is where the extra time is spent resizing the Entry array
* **/
for (int i = 0 ; i < prime ; i++)
{
destinationArray[i] = new Entry( );
}
/* *********************************************** */
我必须初始化每个数组元素作为引用类型的原因可以在 MSDN:结构设计中找到。总之:Entry
不要为结构提供默认构造函数。
如果结构定义了默认构造函数,则在创建
结构的数组时,公共语言运行库会自动
对每个数组元素执行默认构造函数。某些编译器(如 C# 编译器)不允许结构
具有默认构造函数。
这其实很简单,我们将借用阿西莫夫的机器人三定律:
…我们从中得到什么:简而言之,对值类型的使用负责。它们快速高效,但如果维护不当(即无意的副本),可能会导致许多意外行为。

网友回答:
我不同意原始帖子中给出的规则。以下是我的规则:
模板简介:该模板名称为【什么时候应该在 C# 中使用结构而不是类?】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【C#】栏目查找您需要的精美模板。