我正在尝试构建一个将列表导出为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;}
}
我需要一种通用的方法来检查List并返回一个可打印的对象。如下所示。
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属性的属性列表,然后遍历列表并对这些属性进行操作?
答案 0 :(得分:4)
创建一个具有成员方法的接口IPrintable
不是一个更好的主意,该成员方法会返回一组可打印属性吗?
例如,像这样:
interface IPrintable
{
ICollection<PrintProperties> GetPrintableProperties();
}
其中PrintProperties类型包含例如2个成员(名称和值)。 ?
然后,您可以将此接口实现到您希望具有此行为的类。
但是,如果您只想坚持使用您的解决方案,并希望有更短的方式来编写它,那么您可以查看LINQ。 我相信这样的事情也应该做到(未经测试):
var printableProperties = obj.GetType().GetProperties().Where (pi => Attribute.IsDefined (pi, typeof(PrintableAttribute)).ToList();
答案 1 :(得分: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;
}
}
}
}