使用自定义属性对FieldList进行排序

时间:2019-01-30 19:40:00

标签: c# reflection attributes

我想按特定顺序检索对象中的字段。我找到了一种使用反射来检索字段的方法,但是不能保证每次都以相同的顺序返回字段。这是我用来检索字段的代码:

ReleaseNote rn = new ReleaseNote();
Type type = rn.GetType();
FieldInfo[] fi = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic);

我发现了this answer to another question,它说明了如何添加自定义属性并使用它对字段进行排序。基于此,我相信我需要通过创建自定义属性“ MyOrderAttribute”来更新我的代码以按排序顺序检索字段,该属性将用于对FieldInfo数组进行排序。

在这里我创建了属性并将其添加到我的字段中:

namespace TestReleaseNotes
{
    [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
    public class MyOrderAttribute : Attribute
    {
        public MyOrderAttribute(int position)
        {
            this.Position = position;
        }

        public int Position { get; private set; }
    }

    class ReleaseNote
    {
        [MyOrder(0)]
        private string title;
        [MyOrder(1)]
        private string status;
        [MyOrder(3)]
        private string implementer;
        [MyOrder(3)]
        private string dateImplemented;
        [MyOrder(4)]
        private string description;

在这里,我尝试使用该属性对字段列表进行排序:

ReleaseNote rn = new ReleaseNote();
Type type = rn.GetType();
FieldInfo[] fi = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic).OrderBy(f => f.Position);

这给了我一个错误“'FieldInfo不包含'Position'的定义,并且找不到可访问的扩展方法'Position'接受类型为'FieldInfo'的第一个参数(您是否缺少using指令或程序集参考?)”

我还尝试了GetCustomAttribute方法,该方法会产生错误“'MyOrderAttribute'是一种类型,在给定的上下文中无效”:

FieldInfo[] fi = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic).OrderBy(f => f.GetCustomAttribute(MyOrderAttribute);

访问MyOrderAttribute并使用它对字段排序的正确语法是什么?

1 个答案:

答案 0 :(得分:1)

使用以下表达式:

FieldInfo[] fi = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic).OrderBy(f => (int?)(f.CustomAttributes.Where(a=>a.AttributeType==typeof(MyOrderAttribute)).FirstOrDefault()?.ConstructorArguments[0].Value) ?? -1).ToArray();

?。和??运算符在这里处理没有排序属性的字段。它将默认的无序字段设置为-1(即在有序列表的开头)。将其替换为int.MaxValue或9999,以将无序字段放在最后。