Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果GetFields()没有';I don’我不能保证秩序,LayoutKind.Sequential是如何工作的_C#_Reflection_Marshalling - Fatal编程技术网

C# 如果GetFields()没有';I don’我不能保证秩序,LayoutKind.Sequential是如何工作的

C# 如果GetFields()没有';I don’我不能保证秩序,LayoutKind.Sequential是如何工作的,c#,reflection,marshalling,C#,Reflection,Marshalling,我需要以保证的顺序获得关于申报顺序的fieldinfo。现在我使用属性来指定顺序 有没有更自动的方法 是否有人知道LayoutKind.Sequential的工作原理,以及我是否能应用它的技术 我看不出LayoutKind.Sequential是如何工作的,除非有一些预编译程序代码添加了属性。指定该类型的字段应该按照它们在源代码中声明的顺序在内存中排列 如果没有该属性,CLR可以通过重新排列字段来优化内存使用 因此,该属性只是添加了元数据,告知CLR不要执行任何会扰乱字段顺序的内存内优化。如果希

我需要以保证的顺序获得关于申报顺序的fieldinfo。现在我使用属性来指定顺序

有没有更自动的方法

是否有人知道
LayoutKind.Sequential
的工作原理,以及我是否能应用它的技术

我看不出
LayoutKind.Sequential
是如何工作的,除非有一些预编译程序代码添加了属性。

指定该类型的字段应该按照它们在源代码中声明的顺序在内存中排列

如果没有该属性,CLR可以通过重新排列字段来优化内存使用


因此,该属性只是添加了元数据,告知CLR不要执行任何会扰乱字段顺序的内存内优化。

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

Type myType = ...
BindingFlags flags = ...
IEnumerable<FieldInfo> orderedFields = myType.GetFields(flags)
                                             .OrderBy(field => field.MetadataToken);
Type myType=。。。
BindingFlags标志=。。。
IEnumerable orderedFields=myType.GetFields(标志)
.OrderBy(field=>field.MetadataToken);
根据经验,以这种方式对字段进行排序的结果是,,尽管没有记录在案


顺便说一句,这个问题并不完全有意义;没有任何理由相信反射API与运行时如何在内存中布局对象有任何关系。

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

var fields = type.GetFields().OrderBy(f => Marshal.OffsetOf(type, f.Name).ToInt32());

享受吧

+1。我也很有兴趣看到这一点。这是为了在自定义封送器无法保证具有不同本机大小的对象上的大小时自动封送。(在自定义封送拆收器上获取大小不会为您提供指向实际数据或结构的指针,以便在对象可能具有不同本机大小的情况下进行操作)。因此,如果说我想为任何数组或字符串预加一个大小或计数,我必须手动进行,因为我不能使用自定义封送拆收器并要求对象提供其本机数据大小。这只是说明了GetFields()的实现,而不是CLR实现成员布局的方式。反射数据的缓存是问题所在。在.NET 2 btw中进行了重大修改,但不太确定它是否仍然正确。元数据可以(我怀疑是,并且有证据证明是)独立于它在托管内存中的排列方式。您确切知道什么?我知道。但是像大多数元数据一样,您可能可以使用reflect访问它。请参阅,您可能可以使用
GetCustomAttributes(typeof(LayoutKind))
-1获得它,因为这并不能回答问题;它只解释了什么是
LayoutKind.Sequential
,这在这里没有问题。除了根据MSDN,这只适用于编组,而不适用于受CLR控制的托管内存中的布局。我不关心对象在托管内存中的布局。我想要的只是一种保证秩序的方法,这样我就可以在本机内存中安排事情。一个顺序说明符就足够了,即使这没有反映在托管布局顺序中。事实上,我更希望这两者不要捆绑在一起。我现在明白你的问题了。更新的问题是“保证声明顺序”元数据标记是否有序,即使未指定顺序?ECMA 335说“标记为
sequentiallayout
的类引导加载程序在发出时保留字段顺序”,这意味着它们在“field”元数据表中的顺序,因此,它们的
元数据标记的顺序是。所以我想说,这个把戏或多或少是有记录的。确认这个答案是正确的。它还确认类/结构必须是sequentiallayout。但请确保特定的LayoutSequential。如果不这样做,封送将按其喜欢的顺序进行,偏移量按该顺序进行。但是,如果MetadataToken解决方案开始失败,这将起作用。
LayoutKind.Sequential
的使用在您自己的问题中提到过,因此我考虑了回答的先决条件。如前所述,
MetadataToken
的使用未经正式记录且不受支持,即使可能会给出正确的实际知识状态结果。另一方面,我的回答是有官方文件证明和支持的。不,我很感激。当我的方法停止工作时,我正在实现它。链接已被书签。我知道这是一个老问题,但是,是否有人知道如何实际强制GetFields()以错误的顺序列出属性,以便我使用上述方法进行修复。现在,GetFields每次都按正确的顺序给我所有东西。因此,我没有证据证明我正在解决问题。您不能强制
GetFields()
以任何顺序返回字段。但您可以将调用的结果按错误的顺序排序,然后再按正确的顺序排序。例如,您可以比较按字母顺序排列字段的
type.GetFields().OrderBy(f=>f.Name)
,以及
type.GetFields().OrderBy(f=>f.Name).OrderBy(f=>Marshal.OffsetOf(type,f.Name).ToInt32())
,希望它们给出正确的顺序。