请参考此代码
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; }
............
}
我需要通过orderAttribute of Display获得类的所有属性。我已经尝试用这个代码做
var prop = typeof(A)
.GetProperties()
.OrderBy(p => ((DisplayAttribute)p.GetCustomAttributes(typeof(DisplayAttribute), true).FirstOrDefault).Order);
但是会导致错误
对象引用不设置对象
的实例
我认为这个问题是因为一些属性在"DisplayAttribute"中没有"Order"属性。
如何处理这种情况?我需要对所有属性进行排序即使有些属性没有order属性的值
您在FirstOrDefault
操作符上缺少括号()
。此外,您还应该处理返回默认值的情况。我建议选择先获取Order
值或默认值。这将为所有没有DisplayAttribute
的属性返回0
:
var prop = typeof(A)
.GetProperties()
.OrderBy(p => p.GetCustomAttributes(typeof(DisplayAttribute), true)
.Cast<DisplayAttribute>()
.Select(a => a.Order)
.FirstOrDefault());
如果你想把没有DisplayAttribute的属性放在最后,你可以提供Int32.MaxValue
作为默认值返回:
.Select(a => a.Order)
.DefaultIfEmpty(Int32.MaxValue)
.First()
试试这个:
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;
或:
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;
这里有一个更完整的答案,允许您在没有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;
}
}
用法:
// Get all the properties of Foo and order them using PropertyInfoComparer
typeof(Foo).GetProperties().OrderBy(arg => arg, new PropertyInfoComparer());
我喜欢比较器的方法。然而,当我尝试它时,我的迭代器一开始就进入了死循环。后来,它开始抛出异常。此外,我还针对第一个属性不包含"Order"描述符的情况对其进行了优化,以避免检查第二个属性。我还将所有注释移到了类描述中:
/// <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);
}
}
不幸的是,那些没有"Order"描述符的类失去了它们的"自然"顺序。因此,我首先检查具有"Order"描述符的任何属性。如果它们中至少有一个具有该描述符,则进行排序。