运行时创建通用Func <t> </t>

时间:2009-03-18 13:45:58

标签: c# .net reflection

我需要实现这个方法:

object GetFactory(Type type);

该方法需要返回Func&lt; T&gt;。其中typeparam'T'是'type'。

所以,我的问题是我不知道如何创建一个Func&lt;?&gt;在运行时使用反射。 Activator.CreateInstance不起作用,因为委托上没有构造函数。

任何想法?

4 个答案:

答案 0 :(得分:25)

您使用Delegate.CreateDelegate,即来自MethodInfo;下面,我已经硬编码了,但你会使用一些逻辑或Expression来获得实际的创建方法:

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();
    }
}

对于非静态方法,有Delegate.CreateDelegate的重载接受目标实例。

答案 1 :(得分:0)

我认为通常的方法是让“哑”版本成为你在runtme上欺骗的东西,然后提供一个帮助扩展方法来提供类型安全的版本。

答案 2 :(得分:0)

您可以创建Expression对象而不是func,并编译()表达式以获取Func委托。

答案 3 :(得分:0)

我将它与EF Core中的泛型一起使用,包括制作Expression >(例如,Where子句),您可以将MakeGenericType调用与嵌套的泛型链接起来。

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