Matt Roberts
Matt Roberts

Reputation: 26877

Reflection - how to get value at specified index of parameter

I'm trying to get the value of a specified index of a property using reflection.

This answer works for standard properties that are of type List<> for example, but in my case, the collection I am trying to work with is of a different format:

public class NumberCollection : List<int>
{
    public NumberCollection()
    {
        nums = new List<int>();
        nums.Add(10);
    }

    public new int this[int i]
    {
        get { return (int) nums[i]; }
    }

    private List<int> nums;

}

public class TestClass
{
    public NumberCollection Values { get; private set; }

    public TestClass()
    {
        Values = new NumberCollection();
        Values.Add(23);
    }
}


class Program
{
    static void Main(string[] args)
    {
        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;
        // Code will ERROR on the next line...
        PropertyInfo pi2 = collection.GetType().GetProperty(indexerName);
        Object value = pi2.GetValue(collection, new Object[] { 0 });

        Console.Out.WriteLine("tc.Values[0]: " + value);
        Console.In.ReadLine();
    }
}

This code gives an AmbiguousMatchException ("Ambiguous match found."). I know my collection class is somewhat contrived, but can anyone help with this?

Upvotes: 4

Views: 2362

Answers (2)

competent_tech
competent_tech

Reputation: 44931

If you are looking for all of the default members, you can ask for Type.GetDefaultMembers(), then examine the members to find the one that you are looking for.

Alternatively, if you know the data type of the indexer, you can call GetPropertyInfo with the type array specifier.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500385

One option is to use

var prop = Type.GetProperties()
               .Where(prop => prop.DeclaringType == collection.GetType())
               .First();

Change Collection.GetType() to another type if you want. But basically: loop over the properties instead of using Type.GetProperty.

Upvotes: 1

Related Questions