C#访问RtFieldInfo.FieldType抛出TypeLoadException及StructLayout用法疑问
异常原因
StructLayoutAttribute特性用于显式控制类型的内存布局,设计初衷是服务于非托管互操作场景,CLR对引用类型使用该特性有严格的校验规则:
- 普通引用类型的内存布局默认由CLR自动管理,继承自自定义父类的引用类型,父类的实例字段会固定排布在子类字段的内存区域之前,这个规则是CLR类型系统的固有约定,不受用户代码控制。
- 当你给
TestClass显式指定[StructLayout(LayoutKind.Sequential)]时,CLR的类型加载器会判定你要完全接管该类型的内存布局规则,此时就会和「父类字段必须前置」的继承布局规则产生冲突,类型加载校验失败,最终抛出System.TypeLoadException。
继承自抽象类的子类能否使用StructLayout特性
分场景判定:
- 如果指定的是
LayoutKind.Auto:可以使用,不会触发异常,但这个配置等价于CLR默认的布局行为,没有实际意义。 - 如果指定的是
LayoutKind.Sequential或LayoutKind.Explicit:不可以,只要子类继承的父类不是object(无论父类是否为抽象类、是否定义实例字段),显式指定这两种布局规则都会触发CLR类型加载校验失败,抛出上述异常。 - 如果确实需要在互操作场景下使用带显式布局的自定义类型,建议改用值类型(struct),或者调整类的继承结构,让需要指定布局的类直接继承自
object,不要继承其他自定义类型。
内容的提问来源于stack exchange,提问作者Carl Walsh
相关产品推荐
相关产品推荐

