C#reflection索引属性

我正在使用reflection编写克隆方法。 如何使用reflection检测属性是否为索引属性? 例如:

public string[] Items { get; set; } 

到目前为止我的方法:

 public static T Clone(T from, List propertiesToIgnore) where T : new() { T to = new T(); Type myType = from.GetType(); PropertyInfo[] myProperties = myType.GetProperties(); for (int i = 0; i < myProperties.Length; i++) { if (myProperties[i].CanWrite && !propertiesToIgnore.Contains(myProperties[i].Name)) { myProperties[i].SetValue(to,myProperties[i].GetValue(from,null),null); } } return to; } 

 if (propertyInfo.GetIndexParameters().Length > 0) { // Property is an indexer } 

对不起,可是

 public string[] Items { get; set; } 

不是索引属性,它只是一个数组类型! 但是以下是:

 public string this[int index] { get { ... } set { ... } } 

你想要的是GetIndexParameters()方法。 如果它返回的数组有多于0个项,则表示它是一个索引属性。

有关更多详细信息,请参阅MSDN文档 。

如果调用property.GetValue(obj,null) ,并且属性IS已编入索引,那么您将获得参数计数不匹配exception。 最好检查属性是否使用GetIndexParameters()编制索引,然后决定要执行的操作。

以下是一些对我有用的代码:

 foreach(obj.GetType()中的PropertyInfo属性.GetProperties())
 {
   object value = property.GetValue(obj,null);
   if(value是object [])
   {
     ....
   }
 }

PS .GetIndexParameters().Length > 0)适用于本文所述的情况: http : //msdn.microsoft.com/en-us/library/b05d59ty.aspx因此,如果您关心名为Chars的属性值类型字符串,使用它,但它不适用于我感兴趣的大多数数组,包括,我很确定,从原始问题的字符串数组。

您可以将索引器转换为IEnumerable

  public static IEnumerable AsEnumerable(this object o) where T : class { var list = new List(); System.Reflection.PropertyInfo indexerProperty = null; foreach (System.Reflection.PropertyInfo pi in o.GetType().GetProperties()) { if (pi.GetIndexParameters().Length > 0) { indexerProperty = pi; break; } } if (indexerProperty.IsNotNull()) { var len = o.GetPropertyValue("Length"); for (int i = 0; i < len; i++) { var item = indexerProperty.GetValue(o, new object[]{i}); if (item.IsNotNull()) { var itemObject = item as T; if (itemObject.IsNotNull()) { list.Add(itemObject); } } } } return list; } public static bool IsNotNull(this object o) { return o != null; } public static T GetPropertyValue(this object source, string property) { if (source == null) throw new ArgumentNullException("source"); var sourceType = source.GetType(); var sourceProperties = sourceType.GetProperties(); var properties = sourceProperties .Where(s => s.Name.Equals(property)); if (properties.Count() == 0) { sourceProperties = sourceType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic); properties = sourceProperties.Where(s => s.Name.Equals(property)); } if (properties.Count() > 0) { var propertyValue = properties .Select(s => s.GetValue(source, null)) .FirstOrDefault(); return propertyValue != null ? (T)propertyValue : default(T); } return default(T); }