2011-07-29 11 views
8

私はクラスのプロパティに適用するカスタム属性を持っています。この属性は、クラスのプロパティをフラットファイルにエクスポートするために使用されます。C#カスタムプロパティ属性を使用してクラスのプロパティを並べ替える方法

属性のプロパティの1つは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 
    } 
} 

UPDATE:私はあなたが正しい属性を持つプロパティをフィルタリングするために、各PropertyInfoにGetCustomAttributes()メソッドを使用することができ、その後、残りを並べ替える必要があります

+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

を昇順ExportAttribute.FieldOrderによって性質を注文していますアイテム。

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

番目のオプション:キーを選択するための関数を作成し、キーセレクター関数は、ここのように定義されるのOrderBy

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を返します。他のデフォルト値を選択することができます。

第2のアプローチでは、順序付けのための他のタイプのセレクターを定義し、定義した新しいセレクターを呼び出すことができます。

関連する問題