请参阅此代码
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; }
............
}
我需要通过order的orderAttribute按顺序获取类的所有属性。我已尝试使用此代码执行
var prop = typeof(A)
.GetProperties()
.OrderBy(p => ((DisplayAttribute)p.GetCustomAttributes(typeof(DisplayAttribute), true).FirstOrDefault).Order);
但是会导致错误
对象引用不设置对象的实例
我认为这个问题是因为某些属性在“DisplayAttribute”中没有“Order”属性。
如何处理这种情况?我需要订购所有属性,即使某些属性没有order属性的值。
答案 0 :(得分:7)
()
运算符上缺少括号FirstOrDefault
。此外,您应该在返回 default 值时处理大小写。我建议在获得第一个或默认值之前选择Order
值。对于没有0
的所有属性,这将返回DisplayAttribute
:
var prop = typeof(A)
.GetProperties()
.OrderBy(p => p.GetCustomAttributes(typeof(DisplayAttribute), true)
.Cast<DisplayAttribute>()
.Select(a => a.Order)
.FirstOrDefault());
如果您希望没有DisplayAttribute的属性为last,则可以提供Int32.MaxValue
作为要返回的默认值:
.Select(a => a.Order)
.DefaultIfEmpty(Int32.MaxValue)
.First()
答案 1 :(得分:3)
试试这个:
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;
答案 2 :(得分:2)
这是一个更完整的答案,可让您更好地控制PropertyInfo
个实例的排序,而不需要DisplayAttribute
属性:
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());
答案 3 :(得分:0)
我喜欢Comparer的方法。但是,当我尝试它时,我的迭代器首先进入死循环。后来,它开始抛出异常。另外,我对第一个属性不包含“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”描述符的任何属性。如果其中至少有一个具有该描述符,则进行排序。