Проверка того, является ли определенный тип делегатом действия
Я пытаюсь проверить, является ли данный тип-делегат action, независимо от количества параметров.
следующий код-единственный способ, которым я знаю, как это сделать.
public static bool IsActionDelegate( this Type source )
{
return source == typeof( Action ) ||
source.IsOfGenericType( typeof( Action<> ) ) ||
source.IsOfGenericType( typeof( Action<,> ) ) ||
....
source.IsOfGenericType( typeof( Action<,,,,,,,,,,,,,,,> ) );
}
IsOfGenericType()
- это еще один мой метод расширения, который делает то, что он говорит, он проверяет, является ли тип заданным общим типом.
другие предложения?
4 ответов
если вы сразу после делегатов, которые имеют тип возврата void, вы можете сделать следующее:
public static bool IsActionDelegate(Type sourceType)
{
if(sourceType.IsSubclassOf(typeof(MulticastDelegate)) &&
sourceType.GetMethod("Invoke").ReturnType == typeof(void))
return true;
return false;
}
это не будет различать Action
и MethodInvoker
(или другие пустые делегаты, если на то пошло). Как и другие ответы, вы можете изучить имя типа, но это пахнет ;-)
Было бы полезно, если бы вы могли уточнить, по какой причине вы хотите идентифицировать Action
делегатов, чтобы увидеть, какой подход будет работать лучше.
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;
}
Это, кажется, работает:
private static bool IsActionDelegate(this Type source)
{
var type = source.Name;
return source.Name.StartsWith("System.Action");
}
пример:
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 и dueces истинны. func является ложным
Это разные типы, не имеющие ничего общего, кроме своего имени. Единственный полуразумный ярлык, который я могу придумать:
public static bool IsActionDelegate( this Type source )
{
return source.FullName.StartsWith("System.Action");
}
конечно не безопасно, но кто декларирует собственные типы в пространстве имен System заслуживает боли и страданий.