Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 运行时创建通用函数<;T>;_C#_.net_Reflection - Fatal编程技术网

C# 运行时创建通用函数<;T>;

C# 运行时创建通用函数<;T>;,c#,.net,reflection,C#,.net,Reflection,我需要实现以下方法: object GetFactory(Type type); 此方法需要返回一个Func,其中typeparam“T”是“type” 所以,我的问题是,我不知道如何在运行时使用反射创建Func。Activator.CreateInstance无法工作,因为委托上没有构造函数 有什么想法吗?我认为通常的方法是让“哑”版本成为您在runtme上模仿的东西,然后提供一个帮助程序扩展方法,在其上提供类型安全版本。您使用委托.CreateDelegate,即从方法信息;下面,我已经硬

我需要实现以下方法:

object GetFactory(Type type);
此方法需要返回一个Func,其中typeparam“T”是“type”

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


有什么想法吗?

我认为通常的方法是让“哑”版本成为您在runtme上模仿的东西,然后提供一个帮助程序扩展方法,在其上提供类型安全版本。

您使用
委托.CreateDelegate
,即从
方法信息
;下面,我已经硬编码了,但是您可以使用一些逻辑,或
表达式
,来获得实际的创建方法:

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();
    }
}
使用系统;
运用系统反思;
类Foo{}
静态类程序
{
静态函数GetFactory()
{
return(Func)GetFactory(typeof(T));
}
静态对象GetFactory(类型)
{
Type funcType=typeof(Func)。MakeGenericType(Type);
MethodInfo method=typeof(Program).GetMethod(“CreateFoo”,
BindingFlags.NonPublic | BindingFlags.Static);
返回Delegate.CreateDelegate(functtype,method);
}
静态Foo CreateFoo(){返回新的Foo();}
静态void Main()
{
Func factory=GetFactory();
Foo-Foo=工厂();
}
}

对于非静态方法,有一个超负荷的
Delegate.CreateDelegate
,它接受目标实例。

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

我在EF-Core中与泛型一起使用它,包括为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);
var someType=SomeDbContext.SomeDataModelExample.GetType();
var funcType1=typeof(Func).MakeGenericType(新类型[]{someType});
var result=Activator.CreateInstance(funcType1);
var result2=Activator.CreateInstance(funcType1,someParams);

因此,这是在IoC容器内部,我必须以强类型依赖项的形式返回对象,不一定知道请求的是Func(可能是Uri或字符串)。Mark,我实际上不知道t是什么。如果我知道T是什么,这将很容易。我修改了问题以更好地陈述我的问题。这并不完全是我需要的,但这将我推向了正确的道路。谢谢你的帮助。哦,前几天我在玩反射,想知道是否有办法在代码中描述泛型类型定义,现在我知道了:List,它大概只能出现在typeof中?@Earwicker:correct;您只需省略所有类型参数,例如,KeyValuePair而不是KeyValuePairI将其用于EF Core中的泛型,包括为Where子句生成表达式,您可以使用嵌套泛型链接MakeGenericType调用。