Iucounu
Iucounu

Reputation: 1660

How can I get index-parameter values from indexed properties via reflection?

System.Reflection.PropertyInfo and System.Reflection.ParameterInfo don't seem to expose any way to get the values used at runtime to access indexed property values. If correct, this means that one must know the index values (i.e. keys) in advance - unlike a dictionary, there is no .Keys or similar construct to give access to those index values.

My goal is to be able to take an indexed property accessible via a string key and use its keys and values to construct a new dictionary. Is there any way to do this?

Upvotes: 1

Views: 2125

Answers (3)

Tony Hopkinson
Tony Hopkinson

Reputation: 20320

There's "no keys" because you hid them inside the getter. What the keys are depends on your implementation for instance you could have a private member of type dictionary and then wrapped it up in a class.

so you could do myClass["SomeKey"] instead of myClass.Values["SomeKey"]

ie you are hiding how Values is implemented in this example by Dictionary<String,int> perhaps.

So you need to add a method to expose the keys to your class, course the bonus ball is you might not need reflection at all.

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726539

Unfortunately, this is not possible, unless the class "cooperates". Since the only difference between an indexer and any other method is that indexer offers a special syntax, iterating over all keys is generally not possible for the same reasons why it is not possible to go through all values returned by a function.

Consider someone writing an "indexer" that takes a string, and returns its reversed value. In C# this would be a valid indexer; however, it would be unusable for the purposes of enumerating all its possible values.

However, classes that expose indexers often implement IEnumerable<...>. For example, IDictionary<K,V> exposes IEnumerable<KeyValuePair<K,V>>, which lets you enumerate keys along with their corresponding values. Of course classes do not have to do it, but when they do, your code can exploit that to construct whatever output that you need.

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1500385

No, there's no way of doing this - because it doesn't make sense to do so.

Like properties, indexers are just methods with some extra metadata. So this:

public int this[int x, int y]
{
    get { return x * y; } 
}

Is just like this:

public int ComputeValue(int x, int y)
{
    return x * y;
}

If the indexer has a setter, that's just another method with an extra parameter as the value being set.

Look at the indexer above - what would you say the "indexed property values" are? It can work with any int values. That's certainly not a typical indexer, but it's entirely valid from a language perspective.

If you're writing an indexer which only accepts some inputs, you can choose to expose that (just as Dictionary<,> exposes a Keys property) but it's up to you to do so.

Upvotes: 1

Related Questions