2009-08-31 202 views
2

我想建立一個通用的方法將excel導出到列表。如果屬性應該打印,則對象將具有屬性。即:反射,屬性和屬性選擇

public class someObject { 
    public int DontPrint {get; set;} 

    [ExcelAttributes(PrintMe = true)] 
    public int PrintMe {get; set;} 


    [ExcelAttributes(PrintMe = true)] 
    public int PrintMeToo {get; set;} 

} 

我需要一個通用的方式來檢查列表並返回一個可打印的對象。像下面這樣。

public AppendCell<T>(List<T> list) 
    var obj = list[0]; 

    PropertyInfo[] propertyInfos; 
    propertyInfos = obj.GetType().GetProperties(BindingFlags.Public | 
              BindingFlags.Instance); 

    foreach (T list1 in list) 
    { 
     foreach (PropertyInfo info in propertyInfos) 
     { 
      object[] customAttr = info.GetCustomAttributes(true); 
      // create cell with data 
      foreach (object o in customAttr) 
      { 
       ExcelAttributes ea = o as ExcelAttributes; 
       if (ea != null && ea.PrintMe ==true) 
       Cell c = new Cell(info.GetValue(list1,null).ToString()) 

      } 

     } 
} 

return c; 
} 

所以...我基本上要能夠檢查對象的列表,獲取基於屬性的值可打印性能和打印值的打印屬性。

如果我們創建someObject與價值觀

{DontPrint = 0, PrintMe = 1, PrintMeToo = 2} 
{DontPrint = 0, PrintMe = 4, PrintMeToo = 5} 
{DontPrint = 0, PrintMe = 3, PrintMeToo = 8} 

我希望看到一個列表:

1 2 
4 5 
3 8 

代碼類似於張貼做什麼,我需要的。是否有更簡潔的方式來獲取具有PrintMe屬性的屬性列表,然後遍歷列表並對這些屬性執行操作?

回答

4

創建一個接口IPrintable是不是一個更好的主意,它有一個成員方法,它會返回一組可打印的屬性?
例如,是這樣的:

interface IPrintable 
{ 
    ICollection<PrintProperties> GetPrintableProperties(); 
} 

其中PrintProperties類型包括例如出2個成員(名稱&的值)的。 ?

然後,你可以實現這個接口到你想要有這種行爲的類。但是,如果你只是想堅持使用你的解決方案,並且你希望有一個更短的寫法,那麼你可以看看LINQ。 我相信這樣的事情,應該做的伎倆以及(未測試):有關詳細信息,

var printableProperties = obj.GetType().GetProperties().Where (pi => Attribute.IsDefined (pi, typeof(PrintableAttribute)).ToList(); 
+0

那是一個很好的解決方案。我已經使用了反射屬性。我將一個List 傳遞給print類,它使用反射(自定義屬性)來查看哪個屬性意味着顯示。不過,我很好奇你怎麼用界面來做呢? – Houman 2012-03-12 17:54:28

0

見代碼註釋...

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication5 { 
    internal class Program { 
     static void Main(string[] args) { 

      List<someObject> myList = new List<someObject>(); 

      myList.Add(new someObject() { 
       DontPrint = 0, 
       PrintMe = 1, 
       PrintMeToo = 2 
      }); 

      myList.Add(new someObject() { 
       DontPrint = 0, 
       PrintMe = 4, 
       PrintMeToo = 5 
      }); 

      myList.Add(new someObject() { 
       DontPrint = 0, 
       PrintMe = 3, 
       PrintMeToo = 8 
      }); 


      string[,] myPrintables = GetPrintables(myList); 

      System.Console.ReadKey(); 
     } 

     public class someObject { 
      public int DontPrint { 
       get; 
       set; 
      } 
      [ExcelAttributes(true)] 
      public int PrintMe { 
       get; 
       set; 
      } 
      [ExcelAttributes(true)] 
      public int PrintMeToo { 
       get; 
       set; 
      } 
     } 

     /// <summary> 
     /// 
     /// </summary> 
     /// <typeparam name="T"></typeparam> 
     /// <param name="list"></param> 
     /// <returns>string[,] - very easy to export to excel in array operation</returns> 
     public static string[,] GetPrintables<T>(System.Collections.Generic.IList<T> list) { 

      List<System.Reflection.PropertyInfo> discoveredProperties = 
       new List<System.Reflection.PropertyInfo>(); 

      System.Type listType = typeof(T); 

      // first get the property infos (not on every iteration) 
      foreach (System.Reflection.PropertyInfo propertyInfo in listType.GetProperties(
       System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)) { 

       // no indexers 
       if (propertyInfo.GetIndexParameters().Length == 0) { 
        ExcelAttributes[] attributes = propertyInfo.GetCustomAttributes(typeof(ExcelAttributes), true) as ExcelAttributes[]; 

        // allowmultiple = false hence length e {0;1} 
        if (attributes != null && attributes.Length == 1) { 

         if (attributes[0].PrintMe) { 
          discoveredProperties.Add(propertyInfo); 
         } 
        } 
       } 
      } 

      int numberOfDiscoveredProperties = discoveredProperties.Count; 

         // can be instantiated only if there are discovered properties, but null may be returned 
      string[,] arrayItems = new string[list.Count, numberOfDiscoveredProperties]; 

      // if we have any printables 
      if (numberOfDiscoveredProperties > 0) { 

       for (int iItem = 0; iItem < list.Count; iItem++) { 

        for (int iProperty = 0; iProperty < numberOfDiscoveredProperties; iProperty++) { 

         object value = discoveredProperties[iProperty].GetValue(list[iItem], null); 
         // value.ToString may not be ideal, perhaps also cache StringConverters 
         arrayItems[iItem, iProperty] = value != null ? value.ToString() : string.Empty; 
        } 

       } 
      } 

      return arrayItems; 
     } 
    } 

    [System.AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] 
    public class ExcelAttributes : System.Attribute { 

     // use readonly field 
     private readonly bool _PrintMe; 

     public ExcelAttributes(bool printMe) { 
      _PrintMe = printMe; 
     } 

     public bool PrintMe { 
      get { 
       return _PrintMe; 
      } 
     } 
    } 
}