lundi 26 juillet 2021

C# dynamic delegate arguments

An external library calls my code using

Delegate.Method.Invoke(Delegate.Target, new object[]{"arg1", new SomeObject()...});

or

Delegate.DynamicInvoke(new object[]{"arg1", new SomeObject()...});

(I have both options available)

I am not able to modify the code of the external library.

I need to make a delegate that receives that Object array as an argument. Note: I do not know the size or the types of the object array, but I could get it dynamically (in a System.Type array).

Example environment:

public class Program
{
    public static void Main()
    {
        // Create the delegate, can modify this part.
        var target = new Program();
        var methodInfo = typeof(Program).GetMethod("Log");
        var parameters = methodInfo.GetParameters().Select(p => p.ParameterType).ToList();
        Type type;
        
        if (methodInfo.ReturnType != typeof(void))
        {
            parameters.Add(methodInfo.ReturnType);
            type = Expression.GetFuncType(parameters.ToArray());
        }
        else
            type = Expression.GetActionType(parameters.ToArray());
        var test = Delegate.CreateDelegate(type, target, methodInfo.Name);
        
        // invoke the delegate.
        Invoke(test);
    }

    // Cant modify this method
    public static object Invoke(Delegate dDelegate)
    {
        // the array is not always the same size
        return dDelegate.DynamicInvoke(new object[]{"cheese"});
    }

    // Can modify this method and its signature
    // This does not work, "Run-time exception (line 33): Object of type 'System.String' cannot be converted to type 'System.Object[]'."
    public void Log(params object[] test)
    {
        Console.WriteLine(test[0].ToString());
    }
}

Is this even possible? If not, is there a workaround?





Aucun commentaire:

Enregistrer un commentaire