views:

191

answers:

3

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();
}
+1  A: 

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.

Gabe
+2  A: 

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), e.g. 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.

itowlson
+1, if you control the class structure then just implement `IEnumerable`, otherwise you're SOL.
Aaronaught
A: 

Wow this is terrible. I was hoping there was a way to find every index set and traverse each value at each index recursively.

I can't believe there is no way to walk through the values set at the indexes.

Ristogod
I'm unsure why you felt the need to vote this down. Is there some reason why expressing my disappointment in a lack of ability to achieve a goal warrants negativity?
Ristogod