我们必须与本机代码进行大量互操作,在这种情况下,使用不需要封送处理的不安全结构要快得多。但是,当结构包含非基本类型的固定大小缓冲区时,我们无法执行此操作。
为什么 C# 编译器要求固定大小缓冲区只能是基本类型?为什么固定大小的缓冲区不能由如下结构组成:
[StructLayout(LayoutKind.Sequential)]
struct SomeType
{
int Number1;
int Number2;
}
C# 中的固定大小缓冲区是通过称为“不透明类”的 CLI 功能实现的。第 I.12.1.6.3 节Ecma-335 http://www.ecma-international.org/publications/standards/Ecma-335.htm描述他们:
一些语言提供多字节数据结构,其内容由直接操作
地址算术和间接运算。为了支持此功能,CLI 允许值类型
以指定的大小创建,但没有有关其数据成员的信息。实例
这些“不透明类”的处理方式与任何其他类的实例完全相同,但是
ldfld、stfld、ldflda、ldsfld 和 stsfld 指令不得用于访问其内容。
“没有关于其数据成员的信息”和“不得使用 ldfld/stfld”是问题所在。第二条规则禁止结构,您需要 ldfld 和 stfld 来访问它们的成员。 C# 编译器无法提供替代方案,结构的布局是运行时实现细节。 Decimal 和 Nullable 已被淘汰,因为它们也是结构体。 IntPtr 已被淘汰,因为它的大小取决于进程的位数,这使得 C# 编译器很难生成用于访问缓冲区的 ldind/stind 操作码的地址。引用类型引用已被淘汰,因为 GC 需要能够找到它们,但根据第一条规则却做不到。枚举类型的大小可变,具体取决于其基类型;听起来像是一个可以解决的问题,但不完全确定他们为什么跳过它。
只剩下 C# 语言规范中提到的那些:sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double 或 bool。只是具有明确尺寸的简单类型。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)