我想按特定顺序检索对象中的字段。我找到了一种使用反射来检索字段的方法,但是不能保证每次都以相同的顺序返回字段。这是我用来检索字段的代码:
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并使用它对字段排序的正确语法是什么?
答案 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,以将无序字段放在最后。