我需要按照在类中声明它们的顺序使用反射来获取所有属性.根据MSDN,使用时无法保证订单GetProperties()
GetProperties方法不以特定顺序返回属性,例如按字母顺序或声明顺序.
但我已经读过,通过订购属性有一个解决方法MetadataToken.所以我的问题是,这样安全吗?我似乎无法在MSDN上找到有关它的任何信息.或者有没有其他方法来解决这个问题?
我目前的实施情况如下:
var props = typeof(T)
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.OrderBy(x => x.MetadataToken);
Run Code Online (Sandbox Code Playgroud) 具体而言,关于字段初始值设定项(在本例中为静态) - ECMA 334中的第17.11节:
如果一个类包含带有初始化程序的任何静态字段,那么这些初始化程序将在执行静态构造函数之前立即以文本顺序执行.
现在,如果我们partial在单独的文件中有多个类,那么该命令是否在任何地方确定?我的直觉说"没有正式定义,但可能与csproj中包含的顺序有关,或者与csc有关的顺序".它是否正确?
(是的,我意识到最好完全避免歧义 - 可能是通过将所有初始化移动到静态构造函数).
例如,如果我有a.cs:
using System;
partial class Program
{
private static int Foo = Write("Foo");
static int Write(string name)
{
Console.WriteLine(name);
return 0;
}
static void Main()
{
Console.WriteLine("[press any key]");
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
并且b.cs:
partial class Program
{
private static int Bar = Write("Bar");
}
Run Code Online (Sandbox Code Playgroud)
和:
<Compile Include="a.cs" />
<Compile Include="b.cs" />
Run Code Online (Sandbox Code Playgroud)
那么这就是Foo然后Bar; 但是,如果是这样的话:
<Compile Include="b.cs" />
<Compile Include="a.cs" />
Run Code Online (Sandbox Code Playgroud)
那么它是Bar …
private string DoStuff(object result, StringBuilder returnBuilder)
{
// get a list of all public properties and order by name
// so we can guarentee that the order of the headers and
// the results are the same
foreach (var prop in result.GetType().GetProperties().OrderBy(x => x.Name))
{
// do something cool
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果没有OrderBy在for循环中我保证List的本机顺序将是在对象中声明属性的顺序