Is there a way to find the declared generic argument type of an instance of an Action delegate?
In the following code the WriteGenericArgumentType function expects and instance of Action<String> but because Action<in T> allows for contravariance callers of the function are able to call it with Action<Object>.
static void Main( )
{
WriteGenericArgumentType( new Action<string>( s => { } ) );
WriteGenericArgumentType( new Action<object>( o => { } ) );
}
static void WriteGenericArgumentType( Action<string> action )
{
Console.WriteLine( DiscoverGenericArgumentType( action ).Name );
}
static Type DiscoverGenericArgumentType( Delegate action )
{
return action.GetType().GetGenericArguments()[0];
}
However, I need to be able to discover the generic argument type that was defined in the signature of WriteGenericArgumentType from the instance of the delegate that is passed to DiscoverGenericArgumentType.
When the code runs I get the following output:
String
Object
But I need it to be:
String
String
For my purposes I cannot change the signature of DiscoverGenericArgumentType and I need that function to return string as the type.
I know I can create my own generic delegate type that doesn’t allow contravariance but I’m looking for a way to not have to change the signature of the API if possible.
Any ideas?
You won’t be able to from inspecting the instance of the
Action<in T>passed in. As you see, it actually is anAction<object>and there’s nothing linking back to the fact that you wanted anAction<string>.However, instead of looking at the parameter, you should look at the signature of the method. This will always be
Action<string>and reflecting/inspecting that will always give you the output you are looking for.