Проверить совместимость метода с данным делегатом? - PullRequest
7 голосов
/ 31 марта 2011

В коде 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());

, но это касается только типов, а не методов - это всегда будет ложным.

Я склонен полагать, что ответ лежит в типе Delegate, но сейчас я просто брожу по FCL.Любая помощь будет оценена.

Ответы [ 4 ]

6 голосов
/ 31 марта 2011

Я бы попробовал:

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

Это попытается создать делегата и вернуть null при ошибке. Если он возвращает ноль, это должно означать, что делегат не может быть создан. Если он возвращает что-то еще, делегат должен быть в порядке.

4 голосов
/ 31 марта 2011

Мне не известен метод в библиотеке отражений, который делает это.

Я не думаю, что это будет слишком сложно. Правило для простых случаев заключается в том, что должно быть сохраняющее представление преобразование из типа возврата метода в возвращаемый тип делегата, и должно быть сохраняющее представление преобразование из каждого из типов параметров делегата в каждый из типов параметров метода. То есть отношение совместимости ковариантно в типе возвращаемого значения и контравариантно в типе параметра , как и следовало ожидать.

Есть более сложные случаи с участием каррированных делегатов, но я думаю, что вы, вероятно, не захотите входить в них, если вы не делаете это, чтобы написать компилятор для функционального языка. (Вы делаете это, чтобы написать компилятор для функционального языка?)

1 голос
/ 31 марта 2011

Может быть более элегантный способ, но вы можете попробовать создать делегата и проверить исключение:

http://msdn.microsoft.com/en-us/library/ms228976.aspx

0 голосов
/ 31 марта 2011

скажем, у вас есть

   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
    }
...