c# - 更改结构的大小是 C# 中的重大更改吗?

标签 c# .net memory struct cil

只是好奇,改变结构/值类型的大小是 C# 中的重大变化吗?结构在内存布局方面往往更敏感,因为更改它们会直接影响数组/其他结构的大小。在其使用的库中结构的布局发生更改后,是否有任何代码中断的示例,无论是二进制还是源代码?

注意:“中断”是指它根本无法编译或 IL 无效。因此,例如,我不会认为这是一个重大变化:

// My.Library v1
public struct MyStruct {}

// My.Library v2
public struct MyStruct { int _field; }

// App code
using My.Library;
using System.Runtime.InteropServices;

Console.WriteLine(Marshal.SizeOf<MyStruct>()); // before printed 1, now prints 4

因为它仍在运行。

最佳答案

对于严格管理的代码,可以通过添加字段来更改大小。

添加字段是非破坏性更改,因为代码将使用新类型重新 JIT-ed,并且所有分配都将使用正确的大小。由于它是值类型,因此无论如何都会使用空值正确初始化新字段。

删除/更改现有字段或属性的类型肯定是重大更改。

值类型是密封的 - 因此没有其他库可以从该类型派生 - 因此与类不同,它们不会产生“这个派生类没有实现新的虚拟属性/接口(interface)方法”的问题。

注意:如果值类型用于互操作或您无法控制的任何其他类型的二进制序列化,则任何更改都会中断。

即其他人使用 MyLib.Point {int x;int y;} 将二进制序列化的点列表保存到文件中。如果现在“MyLib”向 MyLib.Point 添加一个新字段,则序列化数据不再可以通过二进制序列化读取。与 native 互操作类似的问题。

关于c# - 更改结构的大小是 C# 中的重大更改吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37865610/

相关文章:

c# - ListView.SelectedIndices.Count 多选时为零

c# - 如何从 Sharepoint url 获取所有 SSRS 报告?

c# - 在工具提示中显示 Web 表单

c# - 您能否在 .NET 中的运行时更改动态 Web 引用的位置/端点?

c++ - std::deque 内存使用

c# - 通过 Microsoft.Graph 邀请用户会出现错误

c# - 如何为整个类(class)禁用特定的代码分析警告

c# - 两个字符串数组的交集(忽略大小写)

ruby - 使用 rest-client 将文件下载到磁盘而不首先将其全部加载到内存中

c - 理解虚拟内存,重温elf内存映射