Reputation: 19100
I'm trying to check whether a given type is an action delegate, regardless of the amount of parameters.
The following code is the only way I know how to do this.
public static bool IsActionDelegate( this Type source )
{
return source == typeof( Action ) ||
source.IsOfGenericType( typeof( Action<> ) ) ||
source.IsOfGenericType( typeof( Action<,> ) ) ||
....
source.IsOfGenericType( typeof( Action<,,,,,,,,,,,,,,,> ) );
}
IsOfGenericType()
is another extension method of mine, which does what it says, it checks whether the type is of the given generic type.
Any better suggestions?
Upvotes: 7
Views: 3064
Reputation: 908
static Type[] _actionTypes = new[]{
typeof(Action),
typeof(Action<>),
typeof(Action<,>),
typeof(Action<,,>),
typeof(Action<,,,>),
typeof(Action<,,,,>),
typeof(Action<,,,,,>),
typeof(Action<,,,,,,>),
typeof(Action<,,,,,,,>),
typeof(Action<,,,,,,,,>),
typeof(Action<,,,,,,,,,>),
typeof(Action<,,,,,,,,,,>),
typeof(Action<,,,,,,,,,,,>),
typeof(Action<,,,,,,,,,,,,>),
typeof(Action<,,,,,,,,,,,,,>),
typeof(Action<,,,,,,,,,,,,,,>),
typeof(Action<,,,,,,,,,,,,,,,>)
};
private static bool IsAction(Delegate d)
{
return d != null && Array.IndexOf(_actionTypes, d.GetType()) != -1;
}
Upvotes: 4
Reputation: 160922
If you are just after the delegates that have a void return type you could do the following:
public static bool IsActionDelegate(Type sourceType)
{
if(sourceType.IsSubclassOf(typeof(MulticastDelegate)) &&
sourceType.GetMethod("Invoke").ReturnType == typeof(void))
return true;
return false;
}
This would not distinguish between Action
and MethodInvoker
(or other void delegates for that matter) though. As other answers suggest you could examine the type name, but that kinda smells ;-)
It would help if you could clarify for what reason you want to identify Action
delegates, to see which approach would work best.
Upvotes: 7
Reputation: 941635
These are distinct types with nothing in common but their name. The only semi-reasonable shortcut I can think of:
public static bool IsActionDelegate( this Type source )
{
return source.FullName.StartsWith("System.Action");
}
Certainly not fail-safe, but whomever declares his own types in the System namespace deserves some pain and suffering.
Upvotes: 2
Reputation: 11608
This seems to work:
private static bool IsActionDelegate(this Type source)
{
var type = source.Name;
return source.Name.StartsWith("System.Action");
}
Example:
public static class Test
{
public static bool IsActionDelegate(this Type source)
{
var type = source.Name;
return source.Name.StartsWith("Action");
}
}
class Program
{
static void Main(string[] args)
{
Action<string> one = s => { return; };
Action<int, string> two = (i, s) => { return; };
Func<int, string> function = (i) => { return null; };
var single = one.GetType().IsActionDelegate();
var dueces = two.GetType().IsActionDelegate();
var func = function.GetType().IsActionDelegate();
}
}
Single and dueces are true. func is false
Upvotes: 2