You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法反射InteropServices属性?C#反射StructLayoutAttribute异常排查

无法反射类上的StructLayoutAttribute问题解析

问题场景

你编写的C#代码中,给密封类Data标记了[StructLayout(LayoutKind.Sequential, Pack=4)]用于P/Invoke交互,但通过GetCustomAttribute<StructLayoutAttribute>()反射获取该属性时抛出异常,无法拿到配置的Pack值。

核心原因

StructLayoutAttribute应用在类上时,.NET运行时不会将其作为常规自定义属性存储在类型元数据中。因为类的布局配置是供CLR处理P/Invoke、原生序列化这类底层交互直接使用的,运行时会把布局参数(如Pack、LayoutKind)整合到类型的内部布局描述里,而非保留为普通自定义属性,所以通用的GetCustomAttribute方法无法读取到。

解决方案

使用Type类专属的StructLayoutAttribute属性来获取布局配置,这是.NET专门提供的用于读取类型布局信息的API,不管是结构体还是标记了StructLayout的类都能正确获取:

namespace ConsoleApp1;

using System.Data;
using System.Reflection;
using System.Runtime.InteropServices;

internal class Program {
    [StructLayout(LayoutKind.Sequential, Pack=4)]
    public sealed class Data {
    }

    static void Main(string[] args) {
        // 直接通过Type的StructLayoutAttribute属性获取布局配置
        StructLayoutAttribute layout = typeof(Data).StructLayoutAttribute ??
            throw new NoNullAllowedException("layout");
        
        // 验证获取到的Pack值
        Console.WriteLine($"配置的Pack值:{layout.Pack}");
    }
}

补充说明

  • 该方式完全适配你的需求:既保证类能正常支持P/Invoke原生序列化,又能让代码生成器顺利提取Pack值。
  • 对于结构体,GetCustomAttribute通常可以正常读取StructLayoutAttribute,但类的场景必须使用Type.StructLayoutAttribute来获取。

内容的提问来源于stack exchange,提问作者avigt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 13:32:12