Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Reflection and Indexers

Status
Not open for further replies.

MadJock

Programmer
May 25, 2001
318
GB
Hi all,

I'm trying to access all public properties, along with their values, of an object using reflection. So far so good.

My problem comes when I want to get the values of a collection that is exposed through an indexer. I have found the following code online (source:
Code:
            // retrieve the property descriptor for the specified property
            PropertyInfo objProp = GetPropertyDescriptor(obj, strName);
            // get a reference to the collection
            object objCol = objProp.GetValue(obj, new object[0]);
            // find the default property (the indexed one) of the collection
            PropertyInfo objPropIndexer = null;
            MemberInfo[] objaDefaultMembers = objCol.GetType().GetDefaultMembers();
            for (int i = 0; i < objaDefaultMembers.Length; i++)
            {
                if (objaDefaultMembers[i].MemberType == MemberTypes.Property)
                {
                    objPropIndexer = (PropertyInfo)objaDefaultMembers[i];
                }
            }
            // get the element at the specified index
            object[] objParam = new object[1];
            objParam[0] = (object)intIndex;
            object objValue = objPropIndexer.GetValue(objCol, objParam);

My issue is that the index to the indexer is not a number but a string - therefor I cannot access it by position but only by knowing the key.

Can anyone provide any guidance? More code available if required.

Thanks,

MadJock

"Just beacuse you're paranoid, don't mean they're not after you
 
Even if it is a indexed collection you can still iterate through it because it will implement IEnumerable.

I have a recursive method that loops through an object and gives you a string representation of the object property names, types, and values.
Code:
private string ReflectIt(object it, int indent)
{
    if (it == null) return "NULL\n";
    if (it is string) return it.ToString() + "\n";

    StringBuilder everything = new StringBuilder();
    everything.AppendLine();

    if (it is IEnumerable)
    {
        IEnumerator enumerator = ((IEnumerable)it).GetEnumerator();
        int i = 0;
        while (enumerator.MoveNext())
        {
            everything.Append(' ', indent);
            everything.Append(i.ToString());
            everything.Append(":");
            everything.Append(ReflectIt(enumerator.Current, indent));
            i++;
        }
    }
    else
    {
        indent++;
        foreach (PropertyInfo property in it.GetType().GetProperties())
        {
            everything.Append(' ', indent);
            everything.Append(property.Name);
            everything.Append(":");
            everything.Append("[");
            everything.Append(property.PropertyType.Name);
            everything.Append("]:");
            everything.Append(ReflectIt(property.GetValue(it, null), indent));
        }
    }
    return everything.ToString();
}

You can then have an object and do something like override the ToString() (or just expose it in another method) and use the method, like this:
Code:
public override string ToString()
{
    return string.Format("{0}{1}", this.GetType().Name, ReflectIt(this, 0));
}

I haven't tested it a huge amount but I have tested it with lots of different objects including ones that have properties that are arrays, dictionaries, lists, etc.

Hope it helps.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top