2011-07-29 38 views
8

Tôi có một thuộc tính tùy chỉnh mà tôi áp dụng cho các thuộc tính trên một lớp. Thuộc tính này được sử dụng để xuất các thuộc tính của lớp vào một tệp phẳng.C# Cách sắp xếp các thuộc tính trên một lớp bằng thuộc tính thuộc tính tùy chỉnh

Một trong các thuộc tính của thuộc tính là FieldOrder. Tôi cần phải chắc chắn rằng thứ tự mà tôi xuất các thuộc tính của lớp là chính xác. Ngoài ra, không phải tất cả các thuộc tính trên lớp sẽ có thuộc tính tùy chỉnh.

Tôi tìm thấy bài viết này: How do I sort a generic list based on a custom attribute? Giải pháp này giả định tất cả các thuộc tính đều có thuộc tính tùy chỉnh, đây không phải là trường hợp của tôi. Tôi cũng hy vọng cho giải pháp thanh lịch hơn.

Trợ giúp của bạn được đánh giá cao!

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: Tôi ra lệnh cho các thuộc tính của ExportAttribute.FieldOrder Tăng dần

+0

Chỉ là một ý nghĩ, nhưng có lẽ sẽ dễ dàng hơn để làm một xml tuần tự hóa đơn giản, và sau đó viết một thư viện để chuyển đổi xml phẳng đơn giản thành một tệp phẳng. Nó có thể tái sử dụng và bạn có thể bỏ qua tất cả các công việc thiết lập thuộc tính tùy chỉnh và sự phản chiếu này. – asawyer

Trả lời

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

Vì bạn không giải thích cách bạn muốn các thuộc tính mà không có thuộc tính được sắp xếp, tôi đã tạo nó để chúng sẽ ở đầu. Nhưng ý chính của đoạn mã này là:

  1. Lấy thuộc tính
  2. Ném chúng vào một loại vô danh, do đó bạn có thể dễ dàng truy cập vào tất cả các tài sản và các thuộc tính.
  3. Đặt hàng theo số FieldOrder, sử dụng -1 cho các thuộc tính không có thuộc tính. (không chắc chắn những gì bạn muốn ở đây)
  4. Chuyển đổi chuỗi trở lại thành chuỗi PropertyInfo
  5. Chuyển đổi thành mảng PropertyInfo[].
+0

Điều này hiệu quả. Cảm ơn! – Developer22

0

Bạn sẽ có thể sử dụng phương pháp GetCustomAttributes() trên mỗi PropertyInfo để lọc các thuộc tính với các thuộc tính chính xác, và sau đó sắp xếp các còn lại mặt hàng.

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

Bạn có thể sử dụng một trong các tùy chọn sau.

tùy chọn đầu tiên: vượt qua chức năng ẩn danh để OrderBy

return allProperties.OrderBy(m => m.GetCustomAttribute<ExportAttribute>() == null ? -1 : 
             m.GetCustomAttribute<ExportAttribute>().FieldOrder).ToList(); 

tùy chọn thứ hai: tạo ra các chức năng để lựa chọn phím và vượt qua nó để OrderBy

return allProperties.OrderBy(KeySelector).ToList(); 

Chức năng chọn quan trọng được định nghĩa là ở đây :

public static int KeySelector(PropertyInfo info) 
    { 
     ExportAttribute attr = info.GetCustomAttribute<ExportAttribute>(); 
     return attr == null ? -1 : attr.FieldOrder; 
    } 

Nếu thuộc tính không có ExportAttribute, sele ctor sẽ trả về -1. Bạn có thể chọn bất kỳ giá trị mặc định nào khác.

Cách tiếp cận thứ hai cho phép bạn xác định các loại bộ chọn khác để đặt hàng và chỉ cần gọi bộ chọn mới bạn đã xác định.

Các vấn đề liên quan