【问题标题】:Runtime creation of generic Func<T>通用 Func<T> 的运行时创建
【发布时间】:2010-10-14 02:03:39
【问题描述】:

我需要实现方法:

object GetFactory(Type type);

此方法需要返回一个 Func,其中 typeparam 'T' 是 'type'。

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

有什么想法吗?

【问题讨论】:

    标签: c# .net reflection


    【解决方案1】:

    您使用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 的重载。

    【讨论】:

    • 马克,我实际上不知道 T 是什么。如果我知道 T 是什么,那就很容易了。
    • 我修改了问题以更好地说明我的问题。
    • 不完全是我需要的,但这让我走上了正确的道路。感谢您的帮助。
    • 哦,前几天在玩反射,想知道有没有办法在代码中描述泛型类型定义,现在我知道了:List,大概只能出现在typeof里面?
    • @Earwicker:正确;您只需省略所有类型参数 - 例如, KeyValuePair 而不是 KeyValuePair
    【解决方案2】:

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

    【讨论】:

    • 所以,这是在 IoC 容器的内部,我必须将对象作为强类型依赖项返回,不一定知道请求的是 Func(它可能是一个 Uri 或字符串)。
    【解决方案3】:

    您可以创建 Expression 对象而不是 func,然后 compile() 表达式以获得 Func 委托。

    【讨论】:

      【解决方案4】:

      我在 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);
      

      【讨论】:

      • 我在 EF Core 中将它与泛型一起使用,包括为 Where 子句制作 Expression>,您可以将 MakeGenericType 调用与嵌套泛型链接起来。
      猜你喜欢
      • 1970-01-01
      • 2017-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多