无法反射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
相关产品推荐
相关产品推荐

