首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >StructLayout属性是否与C#中的泛型一起工作?

StructLayout属性是否与C#中的泛型一起工作?
EN

Stack Overflow用户
提问于 2022-04-11 12:22:12
回答 1查看 61关注 0票数 1

下面有一个使用泛型的StructLayout属性的代码。

代码语言:javascript
复制
[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的情况如何。

我试了几个测试来检查这个,根据一个测试,这似乎是工作,但我不知道这是巧合还是总是工作。

我为我糟糕的英语感到抱歉,谢谢你的阅读。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-11 13:08:44

这将如预期的那样起作用。如果将指定打包的StructLayout添加到泛型类,它将向生成的IL添加一个.pack指令。

例如,给定这个类:

代码语言:javascript
复制
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class Test<T1, T2> where T1: struct where T2: struct
{
    public T1 One;
    public T2 Two;
}

它的IL输出如下所示:

代码语言:javascript
复制
.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代码来验证这种打包是否有效:

代码语言:javascript
复制
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

这说明内存中的打包是执行的,即使不使用编组。

有许多类似格式的数据包。因此,我尝试创建能够结合许多其他类型创建新数据包类型的系统。为了便于扩展。

我不太清楚这是什么意思,但将来“受歧视的工会”可能对您有用--但看起来它们不会很快实现,所以可能要过几年才能使用它们(如果有的话)。

还请注意,这只适用于闪存类型!

请参阅这里的文档

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71827778

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档