C# 动态构建函数<;Tn,T>;具有使用表达式的动态实体
注意:C# 动态构建函数<;Tn,T>;具有使用表达式的动态实体,c#,dynamic,delegates,expression,func,C#,Dynamic,Delegates,Expression,Func,注意:Func=可以是任意数量的类型 我最近接了一个我已经工作了一段时间的项目,正在审核代码。在我休息之前,我被一个方法的实施激怒了,所以我花了大约2天的时间来尝试改进它。我正在尝试使用运行时已知的泛型类型参数count、type和return type动态创建一个Func 我现在使用的代码块是以下switch语句:(对不起,格式不正确) 或: var paramCount=member.GetParameters().Count(); 如果(paramCount==0) method=newf
Func
=可以是任意数量的类型
我最近接了一个我已经工作了一段时间的项目,正在审核代码。在我休息之前,我被一个方法的实施激怒了,所以我花了大约2天的时间来尝试改进它。我正在尝试使用运行时已知的泛型类型参数count、type和return type动态创建一个Func
我现在使用的代码块是以下switch语句:(对不起,格式不正确)
或:
var paramCount=member.GetParameters().Count();
如果(paramCount==0)
method=newfunc(()=>member.Invoke(LinkedDocument,null));
else if(paramCount==1)
method=newfunc(param=>member.Invoke(LinkedDocument,new[]{param}));
其他的
方法=新函数(
param=>member.Invoke(
LinkedDocument,param));
哪个有效。。。但是我只是认为可以更动态地涵盖所有方法
public static Type[] _baseFuncTypes = new Type[] { typeof(Func<>), typeof(Func<,>), typeof(Func<,,>), typeof(Func<,,,>), typeof(Func<,,,,>), typeof(Func<,,,,,>), typeof(Func<,,,,,,>), typeof(Func<,,,,,,,>), typeof(Func<,,,,,,,,>) };
private static Type GetFuncType(Type[] parameterTypes, Type returnType)
{
Array.Resize(ref parameterTypes, parameterTypes.Length + 1);
parameterTypes[parameterTypes.Length - 1] = returnType;
return _baseFuncTypes[parameterTypes.Length - 1].MakeGenericType(parameterTypes);
}
public static Type[]\u baseFuncTypes=new Type[]{typeof(Func)、typeof(Func)、typeof(Func)、typeof(Func)、typeof(Func)、typeof(Func)、typeof(Func)};
私有静态类型GetFuncType(类型[]参数类型,类型returnType)
{
Array.Resize(ref parameterTypes,parameterTypes.Length+1);
parameterTypes[parameterTypes.Length-1]=返回类型;
返回_baseFuncTypes[parameterTypes.Length-1].MakeGenericType(parameterTypes);
}
Invokemethod.是的,我是否从代码中正确地理解了所有不同的委托实际上只是对eversameobj.Invoke的调用。它们都是我通过反射获取的类方法。我把前面的循环放在问题里。啊,我看到你的编辑了。现在它更有意义了……对不起,我看错了你的回答。我使用不同数量的参数调用多个方法。请参阅更新。我使用obj
所在的循环进行了更新。当您将不同的委托存储在initalScope中时,如何确保始终将每个特定委托的正确数量的参数传递给该委托?
var assem = System.Reflection.Assembly.GetAssembly(typeof(Func<object>));
var type = assem.GetType(string.Format("Func`{0}", obj.GetParameters().Count()));
var typeArr = obj.GetParameters().Select(param => param.ParameterType).ToList();
typeArr.Add(obj.ReturnType);
var ctrInfo = type.GetConstructor(typeArr.ToArray());
var expType = Expression.New(type);
switch (member.GetParameters().Count())
{
case 0:
method = new Func<dynamic>(() => member.Invoke(LinkedDocument, null));
break;
case 1:
method = new Func<object, dynamic>(param => member.Invoke(LinkedDocument, new[] { param }));
break;
default:
method = new Func<object[], dynamic>(
param => member.Invoke(
LinkedDocument, param));
break;
}
var paramCount = member.GetParameters().Count();
if(paramCount == 0)
method = new Func<dynamic>(() => member.Invoke(LinkedDocument, null));
else if(paramCount == 1)
method = new Func<object, dynamic>(param => member.Invoke(LinkedDocument, new[] { param }));
else
method = new Func<object[], dynamic>(
param => member.Invoke(
LinkedDocument, param));
foreach (var member in LinkedDocument.GetType()
.GetMethods()
.Where(
method =>
method.GetCustomAttributes(
typeof(ScriptingMethodAttribute), true)
.Length != 0))
{
var parameters = member.GetParameters().Select(v => Expression.Parameter(v.ParameterType, v.Name)).ToList();
var caller = Expression.Call(member, parameters);
var delegateType = GetFuncType(member.GetParameters().Select(v => v.ParameterType).ToArray(), member.ReturnType);
var methodLambda = Expression.Lambda(delegateType, caller, parameters);
Delegate method = methodLambda.Compile();
initalScope.Add(member.Name.ToLower(), method);
}
public static Type[] _baseFuncTypes = new Type[] { typeof(Func<>), typeof(Func<,>), typeof(Func<,,>), typeof(Func<,,,>), typeof(Func<,,,,>), typeof(Func<,,,,,>), typeof(Func<,,,,,,>), typeof(Func<,,,,,,,>), typeof(Func<,,,,,,,,>) };
private static Type GetFuncType(Type[] parameterTypes, Type returnType)
{
Array.Resize(ref parameterTypes, parameterTypes.Length + 1);
parameterTypes[parameterTypes.Length - 1] = returnType;
return _baseFuncTypes[parameterTypes.Length - 1].MakeGenericType(parameterTypes);
}