简体   繁体   中英

Dynamically retrieve values of index properties in C#

I am trying to create a SortedList of property names and values for any object. The two methods below iterate an object's properties storing its respective values in a sorted list (if there is a better mechanism for accomplishing this please recommend it).

With my current implementation I am running into issues with Index Properties . Object.GetType Method provides a mechanism to specify an array of index properties but I am unsure how to utilize it to get all of the values for the property. For the time being I'd like to concatenate all of the values into a delimited single string.

private static SortedList<string, string> IterateObjProperties(object obj)
{
    IDictionaryEnumerator propEnumerator = ObjPropertyEnumerator(obj);
    SortedList<string, string> properties = new SortedList<string, string>();

    while (propEnumerator.MoveNext())
    {
        properties.Add(propEnumerator.Key.ToString(),
            propEnumerator.Value is String
            ? propEnumerator.Value.ToString() : String.Empty);
    }

    return properties;
}

private static IDictionaryEnumerator ObjPropertyEnumerator(object obj)
{
    Hashtable propertiesOfObj = new Hashtable();
    Type t = obj.GetType();
    PropertyInfo[] pis = t.GetProperties();

    foreach (PropertyInfo pi in pis)
    {
        if (pi.GetIndexParameters().Length == 0)
        {
            propertiesOfObj.Add(pi.Name,
              pi.GetValue(obj, Type.EmptyTypes).ToString());
        }
        else
        {
            // do something cool to store an index property
            // into a delimited string
        }
    }

    return propertiesOfObj.GetEnumerator();
}

In general, this can't be done. An indexer is a property that takes arguments, and it can take any argument (of the appropriate type): there's no guarantee that there will be a finite set of values:

public class DumbExample
{
  // What constitutes "all the values of" the DumbExample indexer?
  public string this[string s] { get { return s; } }
}

Some classes may provide a way to work out the valid inputs to the indexer (or indexer getter), eg Dictionary<TKey,TValue>.Keys (here, of course, the indexer set can take any TKey, but Keys at least gets you the valid inputs to the getter, which is all you caer about in this case), List<T>.Count , etc., but this will be class-specific. So your code will need to handle each of those as a special case.

There's no way to know all the possible indices for a class instance's index properties. An indexer is a method that takes parameters, so like any other method that takes parameters, there's no way to enumerate all the possible combinations of parameter values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM