Reputation: 1660
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
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
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
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