vendredi 2 décembre 2016

How can I make C# Create.Delegate support inheritance?

I have the following type hierarchy:

public abstract class Parent { }
public class Child : Parent
{
    public Task SayAsync(string arg)
    {
        Console.WriteLine(arg);
        return Task.CompletedTask;
    }    
}

I need to achieve the following:

  • Create any instance of Parent at run-time (this is already solved by calling a Func<Parent> which I obtain elsewhere in the code)
  • Then invoke (on that instance) all the public methods (which always return a Task and accept a string as a parameter) passing in the arg which is not a constant.

The above exists in a hot-path therefore in order to improve performance I am resorting to Cached Delegates so at startup I will be creating the delegates which I will then cache and use when required.

Here is an example I have done explicitly for Child which works but I cannot figure out how to make the delegate accept a Parent (as I won't know the type at compile time).

// If I change Child to Parent, I get "Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type"
private delegate Task Invoker(Child instance, string arg);

void Main()
{
    var instance = new Child(); // This will be obtained by calling a Func<Parent>
    var methodWithArg = instance.GetType().GetMethod("SayAsync");

    var func = GetDelegateWithArg(methodWithArg);

    func(instance, "Foo");
}

private static Invoker GetDelegateWithArg(MethodInfo method)
{
    object pointer = null;
    return (Invoker)Delegate.CreateDelegate(typeof(Invoker), pointer, method);
}

Any ideas or alternatives to help me achieve the goal is appreciated.





Aucun commentaire:

Enregistrer un commentaire