17

I need to implement the method:

object GetFactory(Type type); 

This method needs to return a Func<T> where typeparam 'T' is the 'type'.

So, my problem is that I don't know how to create a Func<?> at runtime using reflection. Activator.CreateInstance doesn't work because there are no constructors on delegates.

Any Ideas?

0

4 Answers 4

30

You use Delegate.CreateDelegate, i.e. from a MethodInfo; below, I've hard-coded, but you would use some logic, or Expression, to get the actual creation method:

using System; using System.Reflection; class Foo {} static class Program { static Func<T> GetFactory<T>() { return (Func<T>)GetFactory(typeof(T)); } static object GetFactory(Type type) { Type funcType = typeof(Func<>).MakeGenericType(type); MethodInfo method = typeof(Program).GetMethod("CreateFoo", BindingFlags.NonPublic | BindingFlags.Static); return Delegate.CreateDelegate(funcType, method); } static Foo CreateFoo() { return new Foo(); } static void Main() { Func<Foo> factory = GetFactory<Foo>(); Foo foo = factory(); } } 

For non-static methods, there is an overload of Delegate.CreateDelegate that accepts the target instance.

Sign up to request clarification or add additional context in comments.

5 Comments

Mark, I don't actually know what T is. If I knew what T is, this would be easy.
I modified the question to better state my problem.
Not exactly what I needed , but this pushed me down the right path. Thanks for your help.
Oooh, was playing with reflection the other day and wondered if there was a way to describe a generic type definition in code, and now I know: List<>, which presumably can only appear inside typeof?
@Earwicker: correct; you simply omit all the type-args - for example, KeyValuePair<,> instead of KeyValuePair<TKey,TValue>
1

I use this with generics in EF Core including making Expression<Func<SomeModelType,bool>> for let's say a Where clause, you can chain MakeGenericType calls with nested generics.

var someType = SomeDbContext.SomeDataModelExample.GetType(); var funcType1 = typeof(Func<>).MakeGenericType(new Type[] { someType }); var result = Activator.CreateInstance(funcType1); var result2 = Activator.CreateInstance(funcType1, someParams); 

1 Comment

I use this with generics in EF Core including making Expression<Func<SomeModelType,bool>> for let's say a Where clause, you can chain MakeGenericType calls with nested generics.
0

I think the usual approach would be to make the "dumb" version be the thing that you spoof at runtme, and then provide a helper extension method to provide the type-safe version on top of it.

1 Comment

So, this is in the bowels of an IoC container, and I have to return the object as a strongly typed dependency, not necessarily knowing that what was requested was a Func<T> (it could be a Uri or string).
0

you could create Expression objects instead of a func, and compile() the expression to get a Func delegate.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.