C# 是行动和行动<;T>;完全不同?

C# 是行动和行动<;T>;完全不同?,c#,generics,delegates,C#,Generics,Delegates,我想检查是否(obj是Action)但不知道它的参数 所以我想执行这段代码,不管obj是Action,Action,还是 操作。。等等 if(obj is Action) { //.. } 它们是相关的,但它们是不同的。它们之间没有继承或接口关系,您可以在它们之间强制转换。唯一的形式关系是它们都是subclassDelegate。除此之外,他们只是。。。这是我们经常谈论的朋友 if(obj is Action) 将适用于无参数版本,但不适用于带参数的版本,因为您需要提前知道T值;您可以

我想检查
是否(obj是Action)
但不知道它的参数

所以我想执行这段代码,不管obj是
Action
Action
,还是
操作
。。等等

if(obj is Action)
{
   //..
}
它们是相关的,但它们是不同的。它们之间没有继承或接口关系,您可以在它们之间强制转换。唯一的形式关系是它们都是subclass
Delegate
。除此之外,他们只是。。。这是我们经常谈论的朋友

if(obj is Action)
将适用于无参数版本,但不适用于带参数的版本,因为您需要提前知道
T
值;您可以检查:

if(obj is Action<int>)
if(obj是动作)

例如,但不是所有的。您可以使用
dynamic
进行作弊(有一些方法可以使用
dynamic
在反射和泛型之间切换,DLR选择正确的泛型类型参数),但在完成此操作时,您最好使用
.DynamicInvoke(args)
编辑:
要区分您试图调用的
操作
变体,只需执行以下操作:

const string TYPENAME = "System.Action";
Type objType = obj.GetType();
if(objType.ToString().StartsWith(TYPENAME)) // it is Action
{
    Type[] genericArguments = objType.GetGenericArguments();
    object[] parameters = new object[genericArguments.Length];
    // fill your parameters

    (obj as MulticastDelegate).DynamicInvoke(parameters);
}

如果第一个
具有泛型类型参数,那么它不会失败吗?@adjan是的,会的,在我发布答案后考虑这个问题。现在添加了一些解释
操作的子类是什么类型的?代理通常不会相互继承。。。事实上,
Action
标记为
sealed
(非常确定所有具体的委托都是)@marcGravel感谢您的提示,现在就修复它。如果您不知道泛型类型参数,您如何调用委托?我建议将您的支票替换为
obj is delegate
。然后您可以动态调用该委托,因为据我所知,这是您想要的。