我有一个自定义属性,我应用于类的属性。此属性用于将类的属性导出为平面文件。
属性的一个属性是FieldOrder
。我需要确保导出类属性的顺序是正确的。此外,并非该类中的所有属性都具有自定义属性。
我发现了这篇文章:How do I sort a generic list based on a custom attribute?此解决方案假设所有属性都具有自定义属性,这不是我的情况。我也希望有更优雅的解决方案。
非常感谢您的帮助!
public interface IFileExport{}
public class ExportAttribute: Attribute
{
public int FieldOrder { get; set; }
public int FieldLength { get; set; }
public ExportAttribute() { }
}
public class ExportClass: IFileExport
{
[ExportAttribute( FieldOrder = 2, FieldLength = 25 )]
public string LastName { get; set; }
[ExportAttribute( FieldOrder=1, FieldLength=25)]
public string FirstName { get; set; }
[ExportAttribute( FieldOrder = 3, FieldLength = 3 )]
public int Age { get; set; }
public ExportClass() { }
}
public class TestClass
{
public static List<PropertyInfo> GetPropertiesSortedByFieldOrder
(IFileExport fileExport)
{
//get all properties on the IFileExport object
PropertyInfo[] allProperties = fileExport
.GetType()
.GetProperties( BindingFlags.Instance | BindingFlags.Public );
// now I need to figure out which properties have the ExportAttribute
//and sort them by the ExportAttribute.FieldOrder
}
}
更新:我通过ExportAttribute.FieldOrder Ascending命令属性
答案 0 :(得分:25)
public static List<PropertyInfo> GetPropertiesSortedByFieldOrder( IFileExport fileExport )
{
PropertyInfo[] allProperties = GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Select(x => new
{
Property = x,
Attribute = (ExportAttribute)Attribute.GetCustomAttribute(x, typeof(ExportAttribute), true)
})
.OrderBy(x => x.Attribute != null ? x.Attribute.FieldOrder : -1)
.Select(x => x.Property)
.ToArray();
}
由于你没有解释如何在没有订购属性的情况下想要属性,我已经做到了这一点,以便它们可以在开头。但是这段代码的要点是:
FieldOrder
排序,使用-1
表示没有属性的属性。 (不知道你想要什么)PropertyInfo
PropertyInfo[]
数组。 答案 1 :(得分:0)
您应该能够在每个PropertyInfo上使用GetCustomAttributes()方法来过滤具有正确属性的属性,然后对其余项进行排序。
答案 2 :(得分:0)
static void Main(string[] args)
{
//get all properties on the IFileExport object
PropertyInfo[] allProperties = fileExport.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
Array.Sort(allProperties, ArrayAttributeComparison);
}
private static int ArrayAttributeComparison(PropertyInfo x, PropertyInfo y)
{
//Do null checks here
ExportAttribute xExportAttribute = GetExportAtribute(x);
ExportAttribute yExportAttribute = GetExportAtribute(x);
//Do null checks here
return xExportAttribute.FieldOrder - yExportAttribute.FieldOrder;
}
private static ExportAttribute GetExportAtribute(PropertyInfo propertyInfo)
{
object[] attributes = propertyInfo.GetCustomAttributes(true);
foreach (var t in attributes)
{
if (t is ExportAttribute)
{
return (ExportAttribute)t;
}
}
return null;
}
答案 3 :(得分:0)
您可以使用以下任一选项。
第一个选项:将匿名函数传递给OrderBy
return allProperties.OrderBy(m => m.GetCustomAttribute<ExportAttribute>() == null ? -1 :
m.GetCustomAttribute<ExportAttribute>().FieldOrder).ToList();
第二个选项:创建选择键的功能并将其传递给OrderBy
return allProperties.OrderBy(KeySelector).ToList();
键选择器功能定义如下:
public static int KeySelector(PropertyInfo info)
{
ExportAttribute attr = info.GetCustomAttribute<ExportAttribute>();
return attr == null ? -1 : attr.FieldOrder;
}
如果属性没有ExportAttribute,则选择器将返回-1。您可以选择任何其他默认值。
第二种方法允许您定义其他类型的选择器以进行排序,只需调用已定义的新选择器即可。