`Type.GetProperties`产权制度 [英] `Type.GetProperties` property order

查看:157
本文介绍了`Type.GetProperties`产权制度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

精简版

MSDN文档的 Type.GetProperties 指出,它返回集合不能保证是按字母顺序或声明顺序,但运行一个简单的测试表明在一般情况按照声明顺序返回。是,你知道在哪里不是这种情况下,有特定的场景?除此之外,什么是建议的替代方案?

The MSDN documentation for Type.GetProperties states that the collection it returns is not guaranteed to be in alphabetical or declaration order, though running a simple test shows that in general it is returned in declaration order. Are there specific scenarios that you know of where this is not the case? Beyond that, what is the suggested alternative?

详细版本

我知道MSDN文档 Type.GetProperties 状态:

I realize the MSDN documentation for Type.GetProperties states:

的getProperties方法在一个特定的
顺序不返回的属性,如字母或声明顺序。您的代码一定不能
依赖于哪些属性返回的顺序上,因为这
为了变化而变化。

The GetProperties method does not return properties in a particular order, such as alphabetical or declaration order. Your code must not depend on the order in which properties are returned, because that order varies.

所以不能保证该方法返回的集合将被勒令任何具体的方式。基于一些测试,我发现返回的属性将出现在他们的类型定义的顺序相反

so there is no guarantee that the collection returned by the method will be ordered any specific way. Based on some tests, I've found to the contrary that the properties returned appear in the order they're defined in the type.

例如:

class Simple
{
    public int FieldB { get; set; }
    public string FieldA { get; set; }
    public byte FieldC { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Simple Properties:");
        foreach (var propInfo in typeof(Simple).GetProperties())
            Console.WriteLine("\t{0}", propInfo.Name);
    }
}



输出:

Output:

Simple Properties:
        FieldB
        FieldA
        FieldC

一种这样的情况下,该不同之处仅略微是当所讨论的类型有父谁也具有特性:

One such case that this differs only slightly is when the type in question has a parent who also has properties:

class Parent
{
    public int ParentFieldB { get; set; }
    public string ParentFieldA { get; set; }
    public byte ParentFieldC { get; set; }
}

class Child : Parent
{
    public int ChildFieldB { get; set; }
    public string ChildFieldA { get; set; }
    public byte ChildFieldC { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Parent Properties:");
        foreach (var propInfo in typeof(Parent).GetProperties())
            Console.WriteLine("\t{0}", propInfo.Name);

        Console.WriteLine("Child Properties:");
        foreach (var propInfo in typeof(Child).GetProperties())
            Console.WriteLine("\t{0}", propInfo.Name);

    }
}



输出:

Output:

Parent Properties:
        ParentFieldB
        ParentFieldA
        ParentFieldC
Child Properties:
        ChildFieldB
        ChildFieldA
        ChildFieldC
        ParentFieldB
        ParentFieldA
        ParentFieldC

$ b ParentFieldC


这意味着的GetProperties 方法发现的属性时,从下往上走到继承链。 。这很好,可以这样来处理

Which means the GetProperties method walks up the inheritance chain from bottom up when discovering the properties. That's fine and can be handled as such.

问题:


  1. 是否有不建议在这里所描述的行为将有所不同,我已经错过了吗?

  2. 如果根据订单的具体情况又是什么的建议的方法?

  1. Are there specific situations where the described behavior would differ that I've missed?
  2. If depending on the order is not recommended then what is the recommended approach?

一个看似明显的解决方案是定义这表明在该属性的应的出现(类似在数据成员属性顺序属性)。是这样的:

One seemingly obvious solution would be to define a custom attribute which indicates the order in which the properties should appear (Similar to the Order property on the DataMember attribute). Something like:

public class PropOrderAttribute : Attribute
{
    public int SeqNbr { get; set; }
}



,然后实现,如:

And then implement such as:

class Simple
{
    [PropOrder(SeqNbr = 0)]
    public int FieldB { get; set; }
    [PropOrder(SeqNbr = 1)]
    public string FieldA { get; set; }
    [PropOrder(SeqNbr = 2)]
    public byte FieldC { get; set; }
}



不过,正如许多人所发现的,这一点,如果你的类型将成为一个严​​重的维护问题有100个特性和需要添加的第一个2之间之一。

But as many have found, this becomes a serious maintenance problem if your type has 100 properties and you need to add one between the first 2.

更新

此处显示的例子只是用于说明性的目的。在我的特定情况下,我使用的是类中定义的消息格式,然后通过类的属性迭代,并抓住他们的属性,看看如何在消息中的特定字段应该demarshaled。消息中的字段的顺序是显著所以在我的类属性的顺序必须显著。

The examples shown here are simply for demonstrative purposes. In my specific scenario, I define a message format using a class, then iterate through the properties of the class and grab their attributes to see how a specific field in the message should be demarshaled. The order of the fields in the message is significant so the order of the properties in my class needs to be significant.

它的工作原理目前只是遍历返回集合从的GetProperties ,但由于文档指出,不建议我一直在寻找理解为什么什么其他选择,我有吗?

It works currently by just iterating over the return collection from GetProperties, but since the documentation states it is not recommended I was looking to understand why and what other option do I have?

推荐答案

订单根本无法保证; 。无论发生什么事....偏偏

The order simply isn't guaranteed; whatever happens.... Happens.

明显的情况下,它可能会改变:

Obvious cases where it could change:


  • 任何实现ICustomTypeDescriptor

  • 什么用TypeDescriptionProvider

但是,一个更微妙的情况:部分类。如果一个类拆分为多个文件时,它们的使用的顺序并不限定。请参见是在"文本顺序" ?在整个局部类正式定义

But a more subtle case: partial classes. If a class is split over multiple files, the order of their usage is not defined at all. See Is the "textual order" across partial classes formally defined?

当然,它甚至没有一个单一(非局部)的定义界定; P

Of course, it isn't defined even for a single (non-partial) definition ;p

但是想象一下

文件1

partial class Foo {
     public int A {get;set;}
}

文件2

partial class Foo {
    public int B {get;set:}
}

这里有A和b之间没有任何正式声明的顺序查​​看链接后怎么看。它的往往的发生,虽然

There is no formal declaration order here between A and B. See the linked post to see how it tends to happen, though.

重新您的编辑;最好的办法是有分别指定元帅信息;一种常见的方法是使用带有一个数字顺序的自定义属性,和装饰用的成员。然后,您可以根据这个号码订购。 protobuf网确实非常类似的东西,坦白说我建议在这里使用现有的序列化库:

Re your edit; the best approach there is to specify the marshal info separately; a common approach would be to use a custom attribute that takes a numeric order, and decorate the members with that. You can then order based on this number. protobuf-net does something very similar, and frankly I'd suggest using an existing serialization library here:

[ProtoMember(n)]
public int Foo {get;set;}

其中n是一个整数。在protobuf网具体的情况下,也有分别指定这些数字,当类型是无法直接控制下,这是有用的API。

Where "n" is an integer. In the case of protobuf-net specifically, there is also an API to specify these numbers separately, which is useful when the type is not under your direct control.

这篇关于`Type.GetProperties`产权制度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆