Jodrell
Jodrell

Reputation: 35746

Instantiate a reflected delegate type

I have a type variable

using System;
using System.Linq;
using System.Reflection;

...

var validateFuncType = typeof(Func<,>).MakeGenericType(someVariableType, typeof(bool));

Now I check if someVariableType follows a convention,

var validateOfType = someVariableType
    .GetMethods(BindingFlags.Instance | BindingFlags.Public)
    .SingleOrDefault(mi =>
        {
            if (mi.Name != "Validate" || mi.ReturnType != typeof(bool))
            {
                return false;
            }

            var parameters = mi.GetParameters();
            return parameters.Length == 0;
        });

then depending on the check

object validateFunc;
if (validateOfType == null)
{
    validateFunc = // some noop func that returns true.
    // e.g.  _ => true;
}
else
{
    validateFunc = // a delegate that calls the conventional validate
    // e.g.  someVariable => someVariable.Validate();
}

instantiate an instance of the delegate type.

Can you help me do that, how can I instantiate validateFuncType, that calls the conventional implementation, if it exists?

Upvotes: 0

Views: 89

Answers (3)

Jodrell
Jodrell

Reputation: 35746

What I did, after noticing that input parameters for Func<> are contravariant.

object validateFunc = validateOfType != null
                ? config => (bool)validateOfType.Invoke(config, new object[0])
                : new Func<object, bool>(_ => true);

I'm not sure if this is better than @Sweeper's answer

Upvotes: 0

Sweeper
Sweeper

Reputation: 274520

If I understand correctly, you are looking for Delegate.CreateDelegate:

var alwaysReturnTrueMethodInfo = typeof(YourClass).GetMethod("AlwaysReturnTrue").MakeGenericMethod(someVariableType);
Delegate validateFunc;
if (validateOfType == null)
{
    validateFunc = Delegate.CreateDelegate(validateFuncType, alwaysReturnTrueMethodInfo);
}
else
{
    validateFunc = Delegate.CreateDelegate(validateFuncType, validateOfType);
}

where AlwaysReturnTrue is a helper static method declared like this:

public static bool AlwaysReturnTrue<T>(T t) { return true }

Upvotes: 1

Youp Bernoulli
Youp Bernoulli

Reputation: 5654

You can do it either by:

// create an object of the type
var obj = Activator.CreateInstance(validateFuncType);

And you'll get an instance of validateFuncType in obj.

Another way is to use reflection:

// get public constructors
var ctors = validateFuncType.GetConstructors(BindingFlags.Public);

// invoke the first public constructor with no parameters.
var obj = ctors[0].Invoke(new object[] { });

This was taken from this SO answer. And because of that this question (and answer) might be marked as duplicate.

Upvotes: 0

Related Questions