[英]Get properties of class by order using reflection
Please refer to this code 请参考此代码
public class A : B
{
[Display(Name = "Initial Score Code", Order =3)]
public Code { get; set; }
[Display(Name = "Initial Score Code", Order =2)]
public Name{ get; set; }
............
}
I need to get all properties of class through order by orderAttribute of Display. 我需要通过order的orderAttribute按顺序获取类的所有属性。 I have tried with this code to do
我试过这个代码
var prop = typeof(A)
.GetProperties()
.OrderBy(p => ((DisplayAttribute)p.GetCustomAttributes(typeof(DisplayAttribute), true).FirstOrDefault).Order);
but it causes an error 但它会导致错误
object reference not to set an instance of object
对象引用不设置对象的实例
I assumed this issue because of some property not having "Order" property in "DisplayAttribute" . 我假设这个问题是因为某些属性在“DisplayAttribute”中没有“Order”属性。
How to handle this kind of situation? 如何处理这种情况? I need to order all the properties even though some property not having the value of order property.
我需要订购所有属性,即使某些属性没有order属性的值。
You are missing brackets ()
on FirstOrDefault
operator. 您在
FirstOrDefault
运算符上缺少方括号()
。 Also you should deal with case when default value is returned. 此外,您应该在返回默认值时处理大小写。 I suggest to select
Order
value before getting first or default value. 我建议在获得第一个或默认值之前选择
Order
值。 That will return 0
for all properties which don't have DisplayAttribute
: 对于没有
DisplayAttribute
所有属性,它将返回0
:
var prop = typeof(A)
.GetProperties()
.OrderBy(p => p.GetCustomAttributes(typeof(DisplayAttribute), true)
.Cast<DisplayAttribute>()
.Select(a => a.Order)
.FirstOrDefault());
If you want properties without DisplayAttribute to be last, you can provide Int32.MaxValue
as default value to be returned: 如果您希望没有DisplayAttribute的属性为last,则可以提供
Int32.MaxValue
作为要返回的默认值:
.Select(a => a.Order)
.DefaultIfEmpty(Int32.MaxValue)
.First()
Try this: 尝试这个:
var props = from p in typeof(A).GetProperties()
let orderAttribute = (DisplayAttribute)(p.GetCustomAttributes(typeof(DisplayAttribute), true))
.FirstOrDefault()
where orderAttribute != null
orderby orderAttribute.Order
select p;
Or: 要么:
var props = from p in typeof(A).GetProperties()
let orderAttribute = (DisplayAttribute)(p.GetCustomAttributes(typeof(DisplayAttribute), true))
.FirstOrDefault()
orderby orderAttribute == null ? 0 : orderAttribute.Order
select p;
Here is a much more complete answer that allows you to better control the ordering of PropertyInfo
instances without DisplayAttribute
attributes: 这是一个更完整的答案,它允许您在没有
DisplayAttribute
属性的情况下更好地控制PropertyInfo
实例的顺序:
public class A
{
[Display(Name = "Initial Score Code", Order = 3)]
public int Code
{
get;
set;
}
[Display(Name = "Initial Score Code", Order = 2)]
public string Name
{
get;
set;
}
}
public class PropertyInfoComparer : IComparer<PropertyInfo>
{
public int Compare(PropertyInfo x, PropertyInfo y)
{
var attribute1 = (DisplayAttribute)x.GetCustomAttributes(typeof(DisplayAttribute)).FirstOrDefault();
var attribute2 = (DisplayAttribute)y.GetCustomAttributes(typeof(DisplayAttribute)).FirstOrDefault();
// If the first property has no attribute, sort it first
if (attribute1 == null)
{
return -1;
}
// If the second property has no attribute, sort it first
if (attribute2 == null)
{
return 1;
}
// Compare the Order properties of both attributes
return attribute1.Order.CompareTo(attribute2.Order);
}
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DisplayAttribute : Attribute
{
public string Name
{
get;
set;
}
public int Order
{
get;
set;
}
}
Usage: 用法:
// Get all the properties of Foo and order them using PropertyInfoComparer
typeof(Foo).GetProperties().OrderBy(arg => arg, new PropertyInfoComparer());
I like the approach with Comparer. 我喜欢Comparer的方法。 However, when I tried it, my iterator went into a dead loop at first.
但是,当我尝试它时,我的迭代器首先进入死循环。 Later, it started throwing exceptions.
后来,它开始抛出异常。 Also, I optimized it for the case when first property doesn't contain "Order" descriptor to avoid even checking for a second one.
另外,我对第一个属性不包含“Order”描述符的情况进行了优化,以避免检查第二个属性。 I also moved all comments into the class description:
我还将所有评论都移到了课程描述中:
/// <summary>
/// If the first property has no attribute, sort it first
/// If the second property has no attribute, sort it first
/// Compare the Order properties of both attributes
/// </summary>
public class PropertyInfoComparer : IComparer<PropertyInfo>
{
public int Compare(PropertyInfo x, PropertyInfo y)
{
if (x == y) return 0;
var attrX = (DisplayAttribute)x.GetCustomAttributes(typeof(DisplayAttribute)).FirstOrDefault();
int? orderX = attrX?.GetOrder();
if (orderX == null) return -1;
var attrY = (DisplayAttribute)y.GetCustomAttributes(typeof(DisplayAttribute)).FirstOrDefault();
int? orderY = attrY?.GetOrder();
if (orderY == null) return 1;
return ((int)orderX).CompareTo((int)orderY);
}
}
Unfortunately, classes that have properties without the "Order" descriptor lose their "natural" order. 不幸的是,具有没有“Order”描述符的属性的类会失去“自然”顺序。 Therefore, I ended up checking for any properties that have the "Order" descriptor first.
因此,我最终检查了首先具有“Order”描述符的任何属性。 If at least one of them has that descriptor, then do the sorting.
如果其中至少有一个具有该描述符,则进行排序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.