C#反射索引属性

C#反射索引属性,c#,reflection,clone,C#,Reflection,Clone,我正在使用反射编写一个克隆方法。如何使用反射检测属性是否为索引属性?例如: 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();

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

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;
}
publicstatict克隆(T from,List propertiesToIgnore),其中T:new()
{
T to=新的T();
类型myType=from.GetType();
PropertyInfo[]myProperties=myType.GetProperties();
for(int i=0;i
您需要的是
GetIndexParameters()
方法。如果它返回的数组包含0个以上的项,则表示它是一个索引属性

有关详细信息,请参阅。

对不起,但是

public string[] Items { get; set; }
不是索引属性,它只是数组类型! 然而,以下是:

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

以下是一些适用于我的代码:

foreach (PropertyInfo property in obj.GetType().GetProperties()) { object value = property.GetValue(obj, null); if (value is object[]) { .... } } foreach(obj.GetType().GetProperties()中的PropertyInfo属性) { object value=property.GetValue(obj,null); 如果(值为对象[]) { .... } } p.S.
.GetIndexParameters().Length>0)
适用于本文中描述的情况:
因此,如果您关心字符串类型的值的名为Chars的属性,请使用该属性,但它不适用于我感兴趣的大多数数组,包括我非常确定的原始问题中的字符串数组。

如果调用
property.GetValue(obj,null)
,并且该属性被索引,然后您将得到一个参数计数不匹配异常。最好使用
GetIndexParameters()
检查属性是否已编制索引,然后决定要执行的操作

您可以将索引器转换为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);
    }
公共静态IEnumerable AsEnumerable(此对象o),其中T:class{
var list=新列表();
System.Reflection.PropertyInfo indexerProperty=null;
foreach(o.GetType().GetProperties()中的System.Reflection.PropertyInfo pi){
if(pi.GetIndexParameters().Length>0){
索引器属性=pi;
打破
}
}
if(indexerProperty.IsNotNull()){
var len=o.GetPropertyValue(“长度”);
对于(int i=0;is.Name.Equals(property));
if(properties.Count()==0){
sourceProperties=sourceType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic);
properties=sourceProperties.Where(s=>s.Name.Equals(property));
}
如果(properties.Count()>0){
var propertyValue=属性
.Select(s=>s.GetValue(源,空))
.FirstOrDefault();
返回propertyValue!=null?(T)propertyValue:默认值(T);
}
返回默认值(T);
}

这不是索引属性,而是返回数组的属性。此问题需要主持人更改。这是google查找索引器属性的最佳结果,但代码示例并没有说明这一点。下面一半的答案回答了问题,一半是代码示例。好吧,但是你如何通过反射找到它?我认为这只处理单整数索引器属性,对吗?没有基于字符串的索引器,没有多个索引参数。。。还是我遗漏了什么?@CodeJockey-你可能是对的;我很难让它与
字符串
输入类型一起工作。它挂在
Chars
索引属性上。除非我自己错过了什么。。。
    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);
    }