如何使用反射处理数组

时间:2010-09-19 21:38:11

标签: c# reflection

我正在编写一些验证码。代码将传递给Web服务的数据并决定它是否可以执行操作,或者向调用者返回他们错过某些字段等的消息。

除了数组之外,我主要使用它。我使用[RequiredField]属性标记属性以表示所需的字段。所以如果这是我的一些数据,

public enum EnumTest
{
    Value1,
    Value2
}

[DataContract]
public class DummyWebserviceData
{
    [DataMember]
    [RequiredField]
    public EnumTest[] EnumTest{ get; set; }

    [DataMember]
    [RequiredField]
    public DummyWebserviceData2[] ArrayOfData { get; set; }
}

[DataContract]
public class DummyWebserviceData2
{
    [DataMember]
    [RequiredField]
    public string FirstName { get; set;}

    [DataMember]
    [RequiredField]
    public string LastName { get; set;}

    [DataMember]
    public string Description { get; set;}
}

那我该怎么办?我有日期验证和字符串工作。它使用递归来达到数据所需的任何深度。

但是......那么那两个阵列呢。第一个是枚举数组。我想在这种情况下检查数组是否为空。

第二个是DummyWebserviceData2值的数组。我需要将每个值拉出来并单独查看。

为了简化我编写的代码,它看起来像这样,

foreach (PropertyInfo propertyInfo in data.GetType().GetProperties())
{
    if (propertyInfo.PropertyType.IsArray)
    {
        // this craps out

        object[] array = (object[])propertyInfo.GetValue(data, new object[] { 0 });

    }
}

所以在我看来,第一件事是我可以告诉它是一个数组。但是,如何判断数组中有多少项呢?

4 个答案:

答案 0 :(得分:24)

在运行时,对象将从Array数据类型(this MSDN topic details that)动态子类化,因此您无需反映到数组中,可以强制转换objectArray,然后使用Array.GetValue实例方法:

Array a = (Array)propertyInfo.GetValue(data);
for(int i = 0; i< a.Length; i++)
{
  object o = a.GetValue(i);
}

您也可以迭代一个数组 - 从.Net 2.0开始:

  

在.NET Framework 2.0版中,Array类实现System.Collections.Generic :: IList,System.Collections.Generic :: ICollection和System.Collections.Generic :: IEnumerable泛型接口。

您不需要知道T,因为从中可以获得IEnumerable;然后你可以使用Cast()操作,或者只是在object级别工作。

顺便提一下,您的代码无效的原因是您无法将MyType[]数组转换为object[],因为object[]不是{{1}的基本类型} - 只有MyType[]

答案 1 :(得分:5)

这种方法效果很好,而且代码很简单。

var array = ((IEnumerable)propertyInfo.GetValue(instance)).Cast<object>().ToArray();

答案 2 :(得分:4)

foreach (PropertyInfo propertyInfo in data.GetType().GetProperties())
{
    if (propertyInfo.PropertyType.IsArray)
    {
        // first get the array
        object[] array = (object[])propertyInfo.GetValue(data)

        // then find the length
        int arrayLength = array.GetLength(0);

        // now check if the length is > 0

    }
}

答案 3 :(得分:0)

数组的答案很好,但如上所述,它不适用于其他一些集合类型。如果您不知道您的收藏品是什么类型,请尝试以下内容:

IEnumerable<object> a = (IEnumerable<object>)myPropInfo.GetValue(myResourceObject);
// at least foreach now is available
foreach (object o in a)
{
    // get the value
    string valueAsString = o.ToString();
}