迭代自定义对象的属性名称和值

时间:2009-09-01 21:00:02

标签: asp.net vb.net reflection

我正在尝试创建导出Excel / CSV函数,该函数将遍历自定义对象并首先输出属性名称,然后输出值。我想只在必要时使用反射,所以我在输出标题时尝试保存属性名称,然后重复使用它们来打印值。

这可能吗?我有点厌倦在循环中使用反射但是有更好的方法吗?

Psuedo代码:

Dim Cust1 = New Customer("Tom", "123 Main Street")
Dim Cust2 = New Customer("Mike", "456 Main Street")
Dim Cust3 = New Customer("Joe", "789 Main Street")
Dim CustList As New Arraylist()
CustList.Add(Cust1)
CustList.Add(Cust2)
CustList.Add(Cust3)

CSVExport(CustList, New Customer())


Function CSVExport(List As ArrayList, CustomObject as Object) As StringWriter
Dim sw as Stringwriter
dim proplist as arraylist

'output header

Foreach CustProperty as System.Reflection.PropertyInfo CustomObject.GetType().GetProperties()
    proplist.add(CustProperty.Name)
    sw.write(CustProperty + ",")
EndFor

'output body
'??
'??  Here I'd like to loop through PropList and List instead of using reflection
'??

Return Sw

End Function

2 个答案:

答案 0 :(得分:1)

无论您是否将名称存储在列表中,都会反映出来。

您是否对CustomObject有一定程度的控制权。您可以将信息存储在CustomObject中,并在不使用反射的情况下查询该信息。例如,这是我用于基本域对象的代码。

public class DomainObject 
{
    private HashTable _values = new HashTable();

    public HashTable Properties
    {
        get 
        {
             return _values;
        }
    }

    protected void SetValue<T>(string property, T value)
    {
        if (_values.ContainsKey(property))
        {
            _values[property] = value;
        }
        else 
        {
            _values.Add(property, value);
        }
    }

    protected T GetValue<T>(string property)
    {
        if (_values.ContainsKey(property))
        {
            return (T)_values[property];
        }
        else 
        {
            return default(T);
        }
    }
}


public class TootsieRoll : DomainObject 
{
     public string Size
     {
         get { return GetValue<string>("Size"); }
         set { SetValue<string>("Size",value); }
     }

     public string Flavor
     {
        get { return GetValue<string>("Flavor"); }
        set { SetVlaue<string>("Flavor", value); }
     }

    public int Ounces
    {
       get { return GetValue<int>("Ounces"); }
       set { SetValue<int>("Ounces", value); }
    }
}

现在,您的CSV代码只需要访问并遍历从DomainObject继承的“Properties”HashTable中的Key =&gt;值对,以获取名称和值。但显然这只有在你对对象有一定程度的控制才能使它们从DomainObject继承的情况下才有效,并且它不会涉及30年的重建你所有的属性访问器。如果是这种情况,那么反思就是您的选择。

答案 1 :(得分:0)

在您的伪代码中,您已经使用反射填充了一个arraylist。如果您只想循环遍历ArrayList,则可以查看ArrayList Class MSDN entry。它展示了如何实现IEnumerable来迭代你的数组列表,例如:

Dim obj As [Object]

For Each obj In CType(myList, IENumberable)
    Console.Write(" : {0}", obj)
Next obj

这是未经测试的,我不确定它应该是CType(myList,IENumberable)还是DirectCast(myList,IENumberable)。

还有另一种选择,使用Object Serialization in VB.Net,一条远不那么走的公路(至少在我们的办公室附近)。