Creating delegate from MethodInfo
Asked Answered
P

2

32

I am currently running into an issue trying to create delegates from MethodInfo. My overall goal is to look through the methods in a class and create delegates for ones marked with a certain attribute. I am trying to use CreateDelegate but I am getting the following error.

Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.

Here is my code

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;
    }
}
Prophylaxis answered 20/6, 2012 at 13:13 Comment(0)
M
64

You're trying to create a delegate from an instance method, but you're not passing in a target.

You could use:

Delegate.CreateDelegate(typeof(TestDelagate), this, method);

... or you could make your method static.

(If you need to cope with both kinds of method, you'll need to do that conditionally, or pass in null as the middle argument.)

Muckworm answered 20/6, 2012 at 13:19 Comment(1)
Makes sense, that works great. I had just looked at the description right after posting this and saw that it said static function. Thanks for pointing out how to do it with an instance.Prophylaxis
O
2

You need a different signature for the delegate, if it has no target. The target needs to be passed as the first argument then

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)
    {

    }
}
Origan answered 27/10, 2017 at 18:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.