Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检查方法与给定委托的兼容性?_C#_.net_Delegates_Typechecking - Fatal编程技术网

C# 检查方法与给定委托的兼容性?

C# 检查方法与给定委托的兼容性?,c#,.net,delegates,typechecking,C#,.net,Delegates,Typechecking,在C#代码中,如何检查给定的方法是否可以由特定的委托类型表示 根据我的类型知识,我首先尝试了以下方法: // The delegate to test against. void TargetDelegate(string msg); // and... var methodInfo = Type.GetMethod(..); // obtain the MethodInfo instance. // try to test it typeof(TargetDelegate).IsAss

在C#代码中,如何检查给定的方法是否可以由特定的委托类型表示

根据我的类型知识,我首先尝试了以下方法:

// The delegate to test against.
void TargetDelegate(string msg);

// and...
var methodInfo = Type.GetMethod(..);  // obtain the MethodInfo instance. 
// try to test it 
typeof(TargetDelegate).IsAssignableFrom(methodInfo.GetType());
但这只涉及类型,而不涉及方法——这永远是错误的

我倾向于相信答案在于类型,但我现在只是在FCL中徘徊。任何帮助都将不胜感激

说你有

   private delegate int MyDelegate(string a);
   private int Foo(string a)
   {

   }

   MethodInfo mFoo = this.GetType().GetMethod("Foo");
   var @delegate = Delegate.CreateDelegate(typeof (MyDelegate), mFoo, false);
   if(@delegate!= null)
   {
      // compatible
    }
    else
    {
       // not compatible
    }

可能有更优雅的方法,但您可以尝试创建委托,并检查是否存在异常:


我不知道反射库中有这样的方法

但我认为这不会太难。简单情况下的规则是,必须有从方法的返回类型到委托的返回类型的保留表示的转换,并且必须有从委托的每个参数类型到方法的每个参数类型的保留表示的转换。也就是说,正如您所期望的,兼容性关系在返回类型中是协变的,在参数类型中是逆变的

还有更复杂的情况涉及curried委托,但我认为您可能不想进入这些情况,除非您这样做是为了为函数式语言编写编译器。(您这样做是为了编写函数式语言的编译器吗?

我会尝试:

Delegate.CreateDelegate(typeof(TargetDelegate), methodInfo, false) != null

这将尝试创建委托,失败时返回null。如果返回null,则表示无法创建委托。如果它返回任何其他内容,则代表必须正常。

不确定这是否有帮助;我假设您已经看到这个@Adam,我不需要创建或调用委托实例。我需要一张简单的支票。然而,如果有人能推断出答案,我会非常高兴。正如Adam所建议的,一种方法是用
methodInfo
调用
CreateDelegate
,看看它是否抛出异常(或返回null,视情况而定)。我想你可以尝试一下CreateDelegate。如果成功,它们是兼容的,如果不兼容,它们就不兼容。它不是非常干净,但我不确定是否有更好的方法。我以为您不想创建委托的实例?我正在为以方法名称为字符串的类编写自定义System.Attribute。我希望这个方法在那个类上,并且有一个特定的签名,这样我就可以从中获取委托实例。我想我们可以省去愚蠢的谦虚。与其说“我不知道反射库中有什么方法可以做到这一点”,不如说“反射库中没有任何方法……”。@Adam:Eric可能会觉得自己容易犯错。:)@亚当-我喜欢这样@Eric总是做一个非常卑微的分包辩论。这比其他任何事情都更难,更鼓舞人心。抵制诱惑@亚当:这与谦逊无关,不管是愚蠢还是其他。我最近写了一篇关于查看双精度位的博客文章,一位评论员问我为什么不调用BitConverter.DoubleToInt64位。因为我不知道有这样的方法,这就是为什么。我不是BCL方面的专家,特别是我不是系统方面的专家;我几乎没用过。(我直接参与元数据表,跳过中间人。)如果您要走这条路线,可能最好使用签名
Delegate.CreateDelegate方法(Type,MethodInfo,Boolean)
并为布尔值传递false。然后检查null而不是异常。看起来Gabe比我先做了:)然后Bala改变了他的。很有趣。我想我应该把它作为回答而不是评论