如何使用反射处理数组

pet*_*ter 18 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;}
}
Run Code Online (Sandbox Code Playgroud)

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

但是......那么那两个阵列怎么样呢.第一个是枚举数组.我想检查一下这个数组不是空的情况.

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

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

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

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

    }
}
Run Code Online (Sandbox Code Playgroud)

所以在我看来,第一件事是我可以告诉它是一个数组.但是,我怎么能告诉数组中有多少项?

And*_*tan 26

在运行时,对象将从Array数据类型(此MSDN主题详细信息)动态子类化,因此您不需要反映到数组中,您可以转换objectArray,然后使用Array.GetValue实例方法:

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

您也可以迭代一个数组 - 从.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[]不是基本类型MyType[]- 只是object.

  • 'Cast()`建议+1.`MyType [] a =((Array)propertyInfo.GetValue(data)).Cast <MyType>().ToArray();` (2认同)

Jim*_*Jim 6

此方法效果很好,并且是简单的代码。

var array = ((IEnumerable)propertyInfo.GetValue(instance)).Cast<object>().ToArray();
Run Code Online (Sandbox Code Playgroud)


Cli*_*ity 5

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

    }
}
Run Code Online (Sandbox Code Playgroud)