23

I am writing a Clone method using reflection. How do I detect that a property is an indexed property using reflection? For example:

public string[] Items
{
   get;
   set;
}

My method so far:

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

6 に答える 6

50
if (propertyInfo.GetIndexParameters().Length > 0)
{
    // Property is an indexer
}
于 2008-11-14T20:57:27.243 に答える
21

悪いけど

public string[] Items { get; set; }

はインデックス付きプロパティではなく、単に配列型です! ただし、次のとおりです。

public string this[int index]
{
    get { ... }
    set { ... }
}
于 2009-01-13T19:49:54.957 に答える
9

あなたが望むのはGetIndexParameters()方法です。返される配列に 0 を超える項目がある場合、それはインデックス付きプロパティであることを意味します。

詳細については、MSDN のドキュメントを参照してください。

于 2008-11-14T20:58:04.120 に答える
2

を呼び出しproperty.GetValue(obj,null)、プロパティがインデックス化されている場合、パラメータ カウントの不一致例外が発生します。を使用してプロパティがインデックス化されているかどうかを確認してGetIndexParameters()から、何をすべきかを決定することをお勧めします。

于 2011-06-17T11:13:18.480 に答える
1

これが私のために働いたいくつかのコードです:

foreach(obj.GetType()。GetProperties()のPropertyInfoプロパティ)
{{
  オブジェクト値=property.GetValue(obj、null);
  if(値はobject [])
  {{
    ...。
  }
}

PS .GetIndexParameters().Length > 0)は、次の記事で説明されているケースで機能します。http: //msdn.microsoft.com/en-us/library/b05d59ty.aspx したがって、文字列型の値に対してCharsという名前のプロパティが気になる場合は、それを使用します。元の質問の文字列配列を含め、私が興味を持っていたほとんどの配列では機能しません。

于 2011-06-07T21:53:11.667 に答える
1

インデクサーを 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);
    }
于 2013-07-02T09:10:33.127 に答える