views:

4473

answers:

2

This (shortened) code..

for (int i = 0; i < count; i++)
{
    object obj = propertyInfo.GetValue(Tcurrent, new object[] { i });
}

.. is throwing a 'TargetParameterCountException : Parameter count mismatch' exception.

The underlying type of 'propertyInfo' is a Collection of some T. 'count' is the number of items in the collection. I need to iterate through the collection and perform an operation on obj.

Advice appreciated.

+2  A: 

Reflection only works on one level at a time.

You're trying to index into the property, that's wrong.

Instead, read the value of the property, and the object you get back, that's the object you need to index into.

Here's an example:

using System;
using System.Collections.Generic;
using System.Reflection;

namespace DemoApp
{
    public class TestClass
    {
        public List<Int32> Values { get; private set; }

        public TestClass()
        {
            Values = new List<Int32>();
            Values.Add(10);
        }
    }

    class Program
    {
        static void Main()
        {
            TestClass tc = new TestClass();

            PropertyInfo pi1 = tc.GetType().GetProperty("Values");
            Object collection = pi1.GetValue(tc, null);

            // note that there's no checking here that the object really
            // is a collection and thus really has the attribute
            String indexerName = ((DefaultMemberAttribute)collection.GetType()
                .GetCustomAttributes(typeof(DefaultMemberAttribute),
                 true)[0]).MemberName;
            PropertyInfo pi2 = collection.GetType().GetProperty(indexerName);
            Object value = pi2.GetValue(collection, new Object[] { 0 });

            Console.Out.WriteLine("tc.Values[0]: " + value);
            Console.In.ReadLine();
        }
    }
}
Lasse V. Karlsen
ok, i understand, thanks for the response. it's now working but would be interested to know about the "Item" property if anyone does know...
flesh
Found it, changed the answer. The attribute was on the class, not on the property. Note that classes that doesn't have an indexer doesn't have the attribute either.
Lasse V. Karlsen
noted - i do the collection check further up in my code. thanks for the update :)
flesh
A: 

I was most of the way there until I saw this, and I am posting this because I didn't see it anywhere else; the key was using GetValue(collection, new Object[] { i }); in the loop rather than trying to use GetValue(collection, new Object[i]); outside the loop. (You can probably ignore the "output" in my example);

private static string Recursive(object o)
{ 
        string output="";
        Type t = o.GetType();
        if (t.GetProperty("Item") != null)
        {
            System.Reflection.PropertyInfo p = t.GetProperty("Item");
            int count = -1;
            if (t.GetProperty("Count") != null && 
                t.GetProperty("Count").PropertyType == typeof(System.Int32))
            {
                count = (int)t.GetProperty("Count").GetValue(o, null);
            }
        if (count > 0)
        {
            object[] index = new object[count];
            for (int i = 0; i < count; i++)
            {
                object val = p.GetValue(o, new object[] { i });
                output += RecursiveWorker(val, p, t);
            }
        }
        return output;
    }
}