我需要按照在类中声明的顺序使用反射来获取所有属性。根据MSDN的规定,在使用
GetProperties()
时无法保证订单。
GetProperties方法不按特定顺序返回属性,如字母顺序或声明顺序。
但我已经了解到,通过按
MetadataToken
对属性进行排序可以解决此问题。所以我的问题是,这安全吗?我似乎在MSDN上找不到任何关于它的信息。或者,有没有其他方法来解决这个问题?
我当前的实现如下所示:
var props = typeof(T)
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.OrderBy(x => x.MetadataToken);
发布于 2013-08-01 23:31:00
在.net 4.5
(and even .net 4.0 in vs2012)
上,使用
[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]
对属性进行额外的排序。
发布于 2012-01-30 21:02:12
如果你使用属性路由,这是我在过去用过的方法;
public static IOrderedEnumerable<PropertyInfo> GetSortedProperties<T>()
return typeof(T)
.GetProperties()
.OrderBy(p => ((Order)p.GetCustomAttributes(typeof(Order), false)[0]).Order);
}
然后像这样使用它;
var test = new TestRecord { A = 1, B = 2, C = 3 };
foreach (var prop in GetSortedProperties<TestRecord>())
Console.WriteLine(prop.GetValue(test, null));
}
在哪里;
class TestRecord
[Order(1)]
public int A { get; set; }