一尘不染

使用反射按声明顺序获取属性

c#

我需要按照在类中声明它们的顺序使用反射来获取所有属性。根据MSDN,使用时无法保证顺序GetProperties()

GetProperties方法不按特定顺序(例如字母顺序或声明顺序)返回属性。

但是我读过,有一种解决方法,可以通过排序属性MetadataToken。所以我的问题是,这样安全吗?我似乎找不到有关MSDN的任何信息。还是有其他解决方法?

我当前的实现如下所示:

var props = typeof(T)
   .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
   .OrderBy(x => x.MetadataToken);

阅读 631

收藏
2020-05-19

共1个答案

一尘不染

在.net 4.5 (甚至vs2012中的.net
4.0)上,您可以使用带有[CallerLineNumber]属性的巧妙技巧来进行反射操作,从而使编译器为您的属性插入顺序更好:

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
public sealed class OrderAttribute : Attribute
{
    private readonly int order_;
    public OrderAttribute([CallerLineNumber]int order = 0)
    {
        order_ = order;
    }

    public int Order { get { return order_; } }
}


public class Test
{
    //This sets order_ field to current line number
    [Order]
    public int Property2 { get; set; }

    //This sets order_ field to current line number
    [Order]
    public int Property1 { get; set; }
}

然后使用反射:

var properties = from property in typeof(Test).GetProperties()
                 where Attribute.IsDefined(property, typeof(OrderAttribute))
                 orderby ((OrderAttribute)property
                           .GetCustomAttributes(typeof(OrderAttribute), false)
                           .Single()).Order
                 select property;

foreach (var property in properties)
{
   //
}

如果必须处理部分类,则可以使用来对属性进行附加排序[CallerFilePath]

2020-05-19