C#按原始顺序获取FieldInfos / PropertyInfos?

时间:2011-03-29 13:38:36

标签: c#

如何将类型FieldInfos / PropertyInfos作为MemberInfo数组按照它们在类中的布局顺序获取?

class Test
{
    public bool First { get; set; }
    public int Second;
    public string Third { get; set; }
}

5 个答案:

答案 0 :(得分:26)

http://msdn.microsoft.com/en-us/library/ch9714z3.aspx

  

GetFields方法不会按特定顺序返回字段,例如按字母顺序或声明顺序。您的代码不得依赖于返回字段的顺序,因为该顺序会有所不同。

http://msdn.microsoft.com/en-us/library/kyaxdd3x.aspx

  

GetProperties方法不以特定顺序返回属性,例如按字母顺序或声明顺序。您的代码不得依赖于返回属性的顺序,因为该顺序会有所不同。

您需要自己定义订单,可能需要使用属性:

class Test
{
    [Order(1)] public bool First { get; set; }
    [Order(2)] public int Second;
    [Order(3)] public string Third { get; set; }
}
...
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, 
    Inherited = true, AllowMultiple = false)]
[ImmutableObject(true)]
public sealed class OrderAttribute : Attribute {
    private readonly int order;
    public int Order { get { return order; } }
    public OrderAttribute(int order) {this.order = order;}
}

答案 1 :(得分:2)

您不能,因为此信息与类的执行或功能无关。你为什么要检索这个信息呢?

答案 2 :(得分:2)

看看Mono.Cecil

如果Serializer能够进行源代码排序,那将不会是因为PDB调试信息。

我认为反射会失去排序,因为它会(可能)返回直接和继承成员的混合。这种混合没有“正确”的排序。

Mono.Cecil将允许您直接访问托管程序集中的结构以及CIL代码。 Mono.cecil摇滚大时间,不会吃你的小狗。它是分析程序集的最佳方法,您甚至 都无法加载它们。

如果你愿意,Mono.Cecil会继续编写一个新的程序集,但这种宣传正在偏离主题。

Go get Mono.Cecil

答案 3 :(得分:1)

行号信息未编译到程序集中,它存储在.PDB文件中以供调试器使用。
虽然从技术上讲,有可能从PDB文件中获取您正在查看的信息,但我认为这也不是一个好主意,因为PDB文件不会出现在生产环境中。即使它存在,也不能保证它与DLL同步。

答案 4 :(得分:1)

我尝试以相反的方式谷歌时发现了更多信息。就像JbEvain指出的那样,确认无法控制编译器在CIL类中输出成员的顺序。 甚至适用于XmlSerializer

这里发布了许多有趣的帖子:

  

关于那个话题,我发现事实上要有可靠的排序(在.NET 2.0中,你也可以使用XmlElementAttribute.Order“显式”控制它)[pluralsight-training.net/community/blogs/tewald/archive / 2006/04 / ......和其他人

这应该为这次讨论提供一个良好的背景。它现在真正取决于原始海报需要这些信息是否甚至可以找到解决方案,如果是的话,找到实现该目标的途径。