Создание делегата из MethodInfo
В настоящее время возникает проблема с созданием делегатов из MethodInfo
. Моя общая цель - изучить методы в классе и создать делегаты для тех, которые отмечены определенным атрибутом. Я пытаюсь использовать CreateDelegate
, но я получаю следующую ошибку.
Нельзя привязываться к целевому методу, потому что его подпись или прозрачность безопасности несовместимы с таковой типа делегата.
Вот мой код
public class TestClass
{
public delegate void TestDelagate(string test);
private List<TestDelagate> delagates = new List<TestDelagate>();
public TestClass()
{
foreach (MethodInfo method in this.GetType().GetMethods())
{
if (TestAttribute.IsTest(method))
{
TestDelegate newDelegate = (TestDelagate)Delegate.CreateDelegate(typeof(TestDelagate), method);
delegates.Add(newDelegate);
}
}
}
[Test]
public void TestFunction(string test)
{
}
}
public class TestAttribute : Attribute
{
public static bool IsTest(MemberInfo member)
{
bool isTestAttribute = false;
foreach (object attribute in member.GetCustomAttributes(true))
{
if (attribute is TestAttribute)
isTestAttribute = true;
}
return isTestAttribute;
}
}
Ответы
Ответ 1
Вы пытаетесь создать делегат из метода экземпляра, но вы не передаете цель.
Вы можете использовать:
Delegate.CreateDelegate(typeof(TestDelagate), this, method);
... или вы можете сделать свой метод статическим.
(Если вам нужно справиться с обоими типами методов, вам нужно сделать это условно или передать null
в качестве среднего аргумента.)
Ответ 2
Вам нужна другая подпись для делегата, если у нее нет цели. Цель должна быть передана как первый аргумент, тогда
public class TestClass
{
public delegate void TestDelagate(TestClass instance, string test);
private List<TestDelagate> delagates = new List<TestDelagate>();
public TestClass()
{
foreach (MethodInfo method in this.GetType().GetMethods())
{
if (TestAttribute.IsTest(method))
{
TestDelegate newDelegate = (TestDelagate)Delegate.CreateDelegate(typeof(TestDelagate), null, method);
delegates.Add(newDelegate);
//Invocation:
newDelegate.DynamicInvoke(this, "hello");
}
}
}
[Test]
public void TestFunction(string test)
{
}
}