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 an Action<object>
and there's nothing linking back to the fact that you wanted an Action<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.