有一個使用具有通用性的 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 位元組的步驟分配。但我不知道泛型案例如何。
當然,我知道泛型型別不支持 marshal 函式,但我想知道 StructLayout 的情況如何。
我嘗試了一些測驗來檢查這一點,根據測驗,它似乎有效,但我不知道這是巧合還是總是有效。
我為我糟糕的英語感到抱歉,感謝您的閱讀。
uj5u.com熱心網友回復:
這將按預期作業。如果將StructLayoutwhich 指定包裝添加到泛型類,它將.pack向生成的 IL 添加指令。
例如,給定這個類:
[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);
}
}
}
}
使用時 this 的輸出Pack = 1是1.
如果將包裝更改為Pack = 4,則輸出為4。
如果您將包裝更改為Pack = 8,則輸出為8.
這表明即使不使用編組,也會執行記憶體中的打包。
有許多類似格式的資料包。所以我嘗試創建可以創建新資料包型別的系統,該系統可以結合許多其他型別。便于擴展。
我不完全確定您的意思是什么,但可能是“歧視性工會”將來可能對您有用-但看起來它們不會很快實施,因此可能會在它們可用之前幾年(如果有的話)。
另請注意,這僅適用于 blittable 型別!
有關檔案,請參見此處
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/460193.html
