2011-07-29 79 views
8

我有適用於類的屬性的自定義屬性。該屬性用於將類的屬性導出到平面文件。C#如何使用自定義屬性屬性對類進行排序

其中一個屬性的屬性是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升序屬性

+0

只是一個想法,但也許它會更容易做一個簡單的XML序列化,然後編寫一個庫,將簡單的平板XML轉換爲平面文件。它可以重用,並且可以跳過所有這些自定義屬性設置工作和反射。 – asawyer

回答

22
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(); 
} 

既然你沒有解釋你怎麼想沒有下令屬性的屬性,我已使他們在開始時。但這種代碼的要點是:

  1. 獲取屬性
  2. 扔他們到一個匿名類型,所以你可以很方便的屬性和屬性兩者。
  3. FieldOrder排序,使用-1查找沒有屬性的屬性。 (不知道你在這裏想要什麼)
  4. 將序列轉換回一個序列PropertyInfo
  5. 將它轉換成PropertyInfo[]數組。
+0

這很好。謝謝! – Developer22

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; 
    } 
0

您可以使用下列選項要麼。

第一種選擇:通過匿名函數來排序依據

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; 
    } 

如果該屬性沒有ExportAttribute,sele ctor將返回-1。您可以選擇任何其他默認值。

第二種方法可以讓您定義其他類型的排序選擇器,只需調用您定義的新選擇器即可。

相關問題