views:

65

answers:

2

I have the following method signature:

public static void InvokeInFuture(Delegate method, params object[] args)
{
    // ...
}

The delegate and the arguments are saved to a collection for future invoking.

Is there any way i can check whether the arguments array satisfies the delegate requirements without invoking it?

Thanks.

EDIT: Thanks for the reflection implementation, but i searching for a built-in way to do this. I don't want to reinvert the wheel, the .NET Framework already have this checking implemented inside Delegate.DynamicInvoke() somewhere, implementation that handles all those crazy special cases that only Microsoft's developers can think about, and passed Unit Testing and QA. Is there any way to use this built-in implementation?

Thanks.

+4  A: 

You can use reflection to get the method signature of the delegate as follows.

using System;
using System.Reflection;

bool ValidateDelegate(Delegate method, params object[] args)
{
    ParameterInfo[] parameters = method.Method.GetParameters();
    if (parameters.Length != args.Length) { return false; }

    for (int i = 0; i < parameters.Length; ++i)
    {
        if (parameters[i].ParameterType.IsValueType && args[i] == null ||
            !parameters[i].ParameterType.IsAssignableFrom(args[i].GetType()))
        {
            return false;
        }
    }

    return true;
}
Steve Guidi
Beat me to it, and you had a code sample!+1 for complete answer to his question.
Aequitarum Custos
Your code not handling inheritance, for example an argument of type FileStream is a valid Stream argument. Your code may work, but the fact is that CLR can check is himself within the delegate.Invoke(). Is there a way to reuse the CLR's checking code? i want to be fully consistent to the CLR.
DxCK
Note: you should not check the type like this, as this will return false for variant instances (e.g. a delegate accepting `object` will return false if you pass a `string` or anything else). I'd suggest to use `parameters[i].ParameterType.IsAssignableFrom(args[i].GetType())` and additionally add checks for value type and `null` (`args[i].getType()` will fail if `args[i]` is `null`).
Lucero
@DxCK: good point. We can check that the type is in the inheritance chain with `IsAssignableFrom`. I'll update the answer.
Steve Guidi
@Steve Guidi: and now what if an argument is null? args[i].GetType() will throw NullReferenceException... I dont want to reinvert the wheel, the CLR sure have good code that doing this and passed Unit Testing and QA, Isn't there a way to use the native CLR's one?
DxCK
If you use `Delegate.Invoke`, then I suspect that a similar check will happen in the `Invoke` implementation to validate the arguments. I'm not aware of a public method that does this. Regarding the `null` value check, I'll adapt the solution given by @Lucero and edit my response.
Steve Guidi
+1  A: 

Looks like the framework basically does the above, with some elimination logic to make sure it keeps a list of already evaluated ones.

GrayWizardx