C# 反射索引属性
Posted
技术标签:
【中文标题】C# 反射索引属性【英文标题】:C# Reflection Indexed Properties 【发布时间】:2010-09-22 10:12:19 【问题描述】:我正在编写一个使用反射的克隆方法。如何使用反射检测属性是索引属性?例如:
public string[] Items
get;
set;
到目前为止我的方法:
public static T Clone<T>(T from, List<string> 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;
【问题讨论】:
那不是索引属性,是返回数组的属性。 这个问题需要版主修改。这是查找索引器属性的最佳 google 结果,但这不是代码示例说明的内容。下面的答案一半回答了问题,一半回答了代码示例。 【参考方案1】:if (propertyInfo.GetIndexParameters().Length > 0)
// Property is an indexer
【讨论】:
【参考方案2】:对不起,但是
public string[] Items get; set;
不是索引属性,它只是一个数组类型! 但是以下是:
public string this[int index]
get ...
set ...
【讨论】:
好的,但是如何通过反射找到它?【参考方案3】:你想要的是GetIndexParameters()
方法。如果它返回的数组有超过 0 项,这意味着它是一个索引属性。
更多详情请见the MSDN documentation。
【讨论】:
【参考方案4】:如果你调用property.GetValue(obj,null)
,并且属性被索引,那么你会得到一个参数计数不匹配的异常。最好检查该属性是否使用GetIndexParameters()
进行索引,然后决定要做什么。
【讨论】:
【参考方案5】:下面是一些对我有用的代码:
foreach(obj.GetType().GetProperties() 中的 PropertyInfo 属性) 对象值 = property.GetValue(obj, null); 如果(值是对象[]) ……附: .GetIndexParameters().Length > 0)
适用于本文描述的案例:http://msdn.microsoft.com/en-us/library/b05d59ty.aspx
因此,如果您关心名为 Chars 的字符串类型值的属性,请使用它,但它不适用于我感兴趣的大多数数组,包括我很确定原始问题中的字符串数组。
【讨论】:
【参考方案6】:您可以将索引器转换为 IEnumerable
public static IEnumerable<T> AsEnumerable<T>(this object o) where T : class
var list = new List<T>();
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<int>("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<T>(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);
【讨论】:
我认为这只处理单整数索引器属性,对吧?没有基于字符串的索引器,没有多个索引参数……还是我遗漏了什么? @CodeJockey — 你可能是对的;我无法让它与String
输入类型一起工作。它挂在Chars
索引属性上。除非我自己错过了什么……以上是关于C# 反射索引属性的主要内容,如果未能解决你的问题,请参考以下文章