如果GetFields()不保证顺序,LayoutKind.Sequential如何工作

Lee*_*ere 21 c# reflection marshalling

我需要在声明顺序的保证顺序中获取fieldinfo.现在我正在使用属性来指定顺序.

有更自动的方式吗?

有没有人知道如何LayoutKind.Sequential工作,如果我可以应用它的技术.

LayoutKind.Sequential除非有一些添加属性的预编译器代码,否则我看不出它是如何工作的.

Ani*_*Ani 17

如果您希望返回的字段的顺序Type.GetFields 是稳定的,请尝试按MetadataToken属性进行排序.

Type myType = ...
BindingFlags flags = ...
IEnumerable<FieldInfo> orderedFields = myType.GetFields(flags)
                                             .OrderBy(field => field.MetadataToken);
Run Code Online (Sandbox Code Playgroud)

根据经验,已经发现以这种方式排序字段以声明顺序返回它们,尽管没有记录.

顺便说一下,问题并不完全有意义; 没有任何理由相信反射API以任何方式与运行时如何在内存中放置对象相关联.

  • ECMA 335确实说"标记为`sequentiallayout`的类引导加载程序保留发出的字段顺序",这意味着它们在"字段"元数据表中的顺序,以及它们的`MetadataToken`的顺序.所以我会说这个技巧或多或少都有记录. (3认同)
  • https://github.com/dotnet/corefx/issues/14606确认此答案有效。它还确认类/结构必须是顺序布局。 (2认同)

unl*_*ely 5

这个问题很老但不是那么老......我现在正在处理同样的问题。而且我更喜欢按照声明的顺序获取字段。以下调用应适用于值类型或格式化的引用类型。

var fields = type.GetFields().OrderBy(f => Marshal.OffsetOf(type, f.Name).ToInt32());
Run Code Online (Sandbox Code Playgroud)

享受!

  • 我知道这是一个老问题,但是,有没有人知道如何实际强制 GetFields() 以不正确的顺序列出属性,以便我使用上述方法进行修复。现在,GetFields 每次都以正确的顺序为我提供所有内容。所以,我没有证据证明我正在解决这个问题。 (2认同)
  • 您不能强制`GetFields()` 以任何顺序返回_fields_。但是您可以以_错误_顺序对调用结果进行排序,然后以_正确_顺序再次排序。例如,您可以比较按字母顺序对字段进行排序的 `type.GetFields().OrderBy(f =&gt; f.Name)` 和 `type.GetFields().OrderBy(f =&gt; f.Name).OrderBy(f =&gt; Marshal.OffsetOf(type, f.Name).ToInt32())`,希望给出_正确的顺序。 (2认同)