Runtime creation of generic Func

后端 未结 4 810
野趣味
野趣味 2020-12-29 07:32

I need to implement the method:

object GetFactory(Type type);

This method needs to return a Func where typeparam \'T\' is the \

相关标签:
4条回答
  • 2020-12-29 08:15

    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.

    0 讨论(0)
  • 2020-12-29 08:22

    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.

    0 讨论(0)
  • 2020-12-29 08:31

    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);
    
    0 讨论(0)
  • 2020-12-29 08:33

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

    0 讨论(0)
提交回复
热议问题