如何使用reflection处理数组

我正在写一些validation码。 代码将传递到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;} } 

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

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

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

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

 foreach (PropertyInfo propertyInfo in data.GetType().GetProperties()) { if (propertyInfo.PropertyType.IsArray) { // this craps out object[] array = (object[])propertyInfo.GetValue(data, new object[] { 0 }); } } 

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

在运行时,对象将从Array数据类型( 此MSDN主题详细信息 )动态子类化,因此您无需反映到数组中,可以将object Array.GetValueArray ,然后使用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 :: IEnumerablegenerics接口。

你不需要知道T ,因为从这些你可以得到一个IEnumerable; 然后你可以使用Cast()操作,或者实际上只在object级别工作。

顺便说一下,你的代码无法工作的原因是因为你不能将MyType[]的数组转换为object[]因为object[]不是MyType[]的基类型 - 只有object是。

 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 } } 

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

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

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

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