C# 如何使用自定义属性对类上的属性进行排序

C# 如何使用自定义属性对类上的属性进行排序,c#,sorting,attributes,properties,C#,Sorting,Attributes,Properties,我有一个自定义属性,可以应用于类的属性。此属性用于将类的属性导出到平面文件 属性的属性之一是FieldOrder。我需要确保导出类属性的顺序是正确的。此外,并非类上的所有属性都具有自定义属性 我发现了这篇文章:此解决方案假设所有属性都具有自定义属性,但我的情况并非如此。我还希望有更优雅的解决方案 非常感谢你的帮助 public interface IFileExport{} public class ExportAttribute: Attribute { public int Fie

我有一个自定义属性,可以应用于类的属性。此属性用于将类的属性导出到平面文件

属性的属性之一是
FieldOrder
。我需要确保导出类属性的顺序是正确的。此外,并非类上的所有属性都具有自定义属性

我发现了这篇文章:此解决方案假设所有属性都具有自定义属性,但我的情况并非如此。我还希望有更优雅的解决方案

非常感谢你的帮助

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
    }
}
公共接口IFileExport{}
公共类ExportAttribute:属性
{
公共int字段顺序{get;set;}
public int FieldLength{get;set;}
公共ExportAttribute(){}
}
公共类导出类:IFileExport
{
[ExportAttribute(FieldOrder=2,FieldLength=25)]
公共字符串LastName{get;set;}
[ExportAttribute(FieldOrder=1,FieldLength=25)]
公共字符串名{get;set;}
[ExportAttribute(FieldOrder=3,FieldLength=3)]
公共整数{get;set;}
公共ExportClass(){}
}
公共类TestClass
{
公共静态列表GetPropertiesSortedByFieldOrder
(IFileExport文件导出)
{
//获取IFileExport对象的所有属性
PropertyInfo[]allProperties=fileExport
.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public);
//现在我需要找出哪些属性具有ExportAttribute
//并按ExportAttribute.FieldOrder对其进行排序
}
}

更新:我正在按ExportAttribute.FieldOrder升序排列属性。您应该能够使用每个PropertyInfo上的方法筛选具有正确属性的属性,然后对其余项进行排序。

公共静态列表GetPropertiesSortedByFieldOrder(IFileExport fileExport)
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();
}
{ PropertyInfo[]allProperties=GetType() .GetProperties(BindingFlags.Instance | BindingFlags.Public) .选择(x=>new { 属性=x, Attribute=(ExportAttribute)Attribute.GetCustomAttribute(x,typeof(ExportAttribute),true) }) .OrderBy(x=>x.Attribute!=null?x.Attribute.FieldOrder:-1) .Select(x=>x.Property) .ToArray(); }
由于您没有解释如何在属性没有排序的情况下使用属性,所以我在开始时就这样做了。但该准则的要点是:

  • 获取属性
  • 将它们转换为匿名类型,以便轻松访问属性和属性
  • 字段排序,对不带属性的属性使用
    -1
    。(不确定您在这里想要什么)
  • 将序列转换回
    PropertyInfo
  • 将其转换为
    PropertyInfo[]
    数组
    您可以使用以下任一选项

    第一个选项:将匿名函数传递给OrderBy

    return allProperties.OrderBy(m => m.GetCustomAttribute<ExportAttribute>() == null ? -1 : 
                                          m.GetCustomAttribute<ExportAttribute>().FieldOrder).ToList();
    
    return allProperties.OrderBy(KeySelector).ToList();
    
    钥匙选择器功能的定义如下所示:

        public static int KeySelector(PropertyInfo info)
        {
            ExportAttribute attr = info.GetCustomAttribute<ExportAttribute>();
            return attr == null ? -1 : attr.FieldOrder;
        }
    
    公共静态int键选择器(PropertyInfo信息)
    {
    ExportAttribute attr=info.GetCustomAttribute();
    返回attr==null?-1:attr.FieldOrder;
    }
    
    如果属性没有ExportAttribute,选择器将返回-1。您可以选择任何其他默认值


    第二种方法允许您定义其他类型的选择器进行排序,只需调用已定义的新选择器即可

    这只是一个想法,但可能更容易进行简单的xml序列化,然后编写一个库将简单的平面xml转换为平面文件。它是可重用的,您可以跳过所有这些自定义属性设置工作和反射。
        public static int KeySelector(PropertyInfo info)
        {
            ExportAttribute attr = info.GetCustomAttribute<ExportAttribute>();
            return attr == null ? -1 : attr.FieldOrder;
        }