I want to itterate over an indexed property that I only have access to via reflection,
but ( and I say this in the full knowledge that there's probably an embarrassingly simple answer, MSDN/Google fail =/ ) I cannot find/think of a way besides incrementing a counter over the PropertyInfo.GetValue(prop, counter)
until the TargetInvocationException
is thrown.
ala:
foreach ( PropertyInfo prop in obj.GetType().GetProperties() )
{
if ( prop.GetIndexParameters().Length > 0 )
{
// get an integer count value, by incrementing a counter until the exception is thrown
int count = 0;
while ( true )
{
try
{
prop.GetValue( obj, new object[] { count } );
count++;
}
catch ( TargetInvocationException ) { break; }
}
for ( int i = 0; i < count; i++ )
{
// process the items value
process( prop.GetValue( obj, new object[] { i } ) );
}
}
}
now, there are some issues with this... very ugly.. solution..
what if it's multi-dimensional or not indexed by integers for example...
heres the test code I'm using to try and get it working if anyone needs it. If anyone's interested I'm making a custom caching system and .Equals doesn't cut it.
static void Main()
{
object str = new String( ( "Hello, World" ).ToArray() );
process( str );
Console.ReadKey();
}
static void process( object obj )
{
Type type = obj.GetType();
PropertyInfo[] properties = type.GetProperties();
// if this obj has sub properties, apply this process to those rather than this.
if ( properties.Length > 0 )
{
foreach ( PropertyInfo prop in properties )
{
// if it's an indexed type, run for each
if ( prop.GetIndexParameters().Length > 0 )
{
// get an integer count value
// issues, what if it's not an integer index (Dictionary?), what if it's multi-dimensional?
// just need to be able to iterate through each value in the indexed property
int count = 0;
while ( true )
{
try
{
prop.GetValue( obj, new object[] { count } );
count++;
}
catch ( TargetInvocationException ) { break; }
}
for ( int i = 0; i < count; i++ )
{
process( prop.GetValue( obj, new object[] { i } ) );
}
}
else
{
// is normal type so.
process( prop.GetValue( obj, null ) );
}
}
}
else
{
// process to be applied to each property
Console.WriteLine( "Property Value: {0}", obj.ToString() );
}
}
The getter of an indexer is just like normal method, except it takes square brackets, not round ones. You wouldn't expect to be able to automatically determine the range of acceptable values for a method, so it's not feasible for an indexer.
Having sequential index numbers in an indexed property is nothing you can bet on.
Indexed properties are not arrays.
Counter example:
Dictionary<int, bool> dictionary = new Dictionary<int, bool>();
dictionary[1] = true;
dictionary[5] = false;
Depending on the type you usually have other methods to get the possible index values, in this case dictionary.Keys
. If it possible with your types I would try in this order
IEnumerable<T>
for the type itself.IEnumerable<T>
property for each indexed property.If you have no specification of valid values and no method of asking what the valid values are, then you are pretty much out of luck.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With