C# 如何使用反射处理数组

C# 如何使用反射处理数组,c#,reflection,C#,Reflection,我正在写一些验证代码。代码将获取传递到web服务的数据,并决定它是否可以执行该操作,或者向调用者返回一条消息,说明他们遗漏了一些字段等 除了阵列之外,它基本上都能正常工作。我正在用[RequiredField]属性标记属性,以表示所需的字段。如果这是我的一些数据 public enum EnumTest { Value1, Value2 } [DataContract] public class DummyWebserviceData { [DataMember]

我正在写一些验证代码。代码将获取传递到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 });

    }
}

所以在我看来,第一件事是我能分辨出它是一个数组。但是我怎样才能知道数组中有多少项呢?

在运行时,对象将从
数组
数据类型()动态地子类化,因此您不需要反映到数组中,您可以将
对象
强制转换为
数组
,然后使用
数组.GetValue
实例方法:

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

    }
}
Array a = (Array)propertyInfo.GetValue(data);
for(int i = 0; i< a.Length; i++)
{
  object o = a.GetValue(i);
}
Array a=(Array)propertyInfo.GetValue(data);
for(int i=0;i
您还可以在数组上迭代-从.Net 2.0开始:

在.NET Framework 2.0版中,数组类实现System.Collections.Generic::IList、System.Collections.Generic::ICollection和System.Collections.Generic::IEnumerable通用接口

你不需要知道
t
,因为你可以从中得到一个IEnumerable;然后,您可以对其使用Cast()操作,或者实际上只在
对象
级别工作


顺便说一句,代码不起作用的原因是您无法将
MyType[]
数组强制转换为
object[]
,因为
object[]
不是
MyType[]
的基本类型-只有
object
是。

数组的答案很好,但如前所述,它不适用于其他一些集合类型。如果您不知道您的收藏类型,请尝试以下方法:

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();
}
IEnumerable a=(IEnumerable)myPropInfo.GetValue(myResourceObject);
//现在至少有foreach可用
foreach(a中的对象o)
{
//获取值
字符串值string=o.ToString();
}

此方法非常有效,而且代码简单

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

close-但这不起作用,因为
data
不是数组,它是一个属性为数组的
对象
,必须首先使用
propertyInfo
来访问数组。请注意,不能使用IList或ICollection接口实现来修改数组内容-正如前面提到的MDSN主题所述-它们都抛出
NotSupportedException
正确。我研究了一下,发现了很多你上面提到的东西。我也确保了数组的秩确实是1。否则,该数组可以是数组[]。谢谢你的帮助。非常感谢。
Cast()
建议+1<代码>MyType[]a=((数组)属性info.GetValue(数据)).Cast().ToArray()这需要对System.Linq as Cast的引用,实际上它是一个扩展方法。加上这些之后,它对我起了作用,谢谢!