下面有一个使用泛型的StructLayout属性的代码。
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class Packet<H, Body1, Body2> : IOutlinePacket
where H : new()
where Body1 : IDeviceBody, new()
where Body2 : INetworkBody, new()
{
H Header = new Header();
Body1 DeviceBody = new Body1();
Body2 NetworkBody = new Body2();
}如果类不是泛型,则H、Body1、Body2的序列将得到保证,并将通过一个1字节的步骤分配。但我不知道通用型的案子怎么样。
当然,我知道一般类型不支持封送函数,但我想知道StructLayout的情况如何。
我试了几个测试来检查这个,根据一个测试,这似乎是工作,但我不知道这是巧合还是总是工作。
我为我糟糕的英语感到抱歉,谢谢你的阅读。
发布于 2022-04-11 13:08:44
这将如预期的那样起作用。如果将指定打包的StructLayout添加到泛型类,它将向生成的IL添加一个.pack指令。
例如,给定这个类:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class Test<T1, T2> where T1: struct where T2: struct
{
public T1 One;
public T2 Two;
}它的IL输出如下所示:
.class public sequential ansi beforefieldinit Test`2<valuetype .ctor ([System.Runtime]System.ValueType) T1, valuetype .ctor ([System.Runtime]System.ValueType) T2>
extends [System.Runtime]System.Object
{
.pack 1
.size 0
.field public !T1 One
.field public !T2 Two
.method public hidebysig specialname rtspecialname instance void .ctor () cil managed
{
IL_0000: ldarg.0
IL_0001: call instance void [System.Runtime]System.Object::.ctor()
IL_0006: ret
}
}注意.pack 1,它指定了打包。
您可以通过按照以下代码编写一些unsafe代码来验证这种打包是否有效:
public static class Program
{
public static void Main()
{
var test = new Test<byte, long>
{
One = 1,
Two = 2
};
unsafe
{
fixed (byte* p1 = &test.One)
fixed (long* p2 = &test.Two)
{
Console.WriteLine((byte*)p2 - p1);
}
}
}
}使用Pack = 1时,它的输出是1。
如果将打包更改为Pack = 4,则输出为4。
如果将打包更改为Pack = 8,则输出为8。
这说明内存中的打包是执行的,即使不使用编组。
有许多类似格式的数据包。因此,我尝试创建能够结合许多其他类型创建新数据包类型的系统。为了便于扩展。
我不太清楚这是什么意思,但将来“受歧视的工会”可能对您有用--但看起来它们不会很快实现,所以可能要过几年才能使用它们(如果有的话)。
还请注意,这只适用于闪存类型!
https://stackoverflow.com/questions/71827778
复制相似问题