C# 使用ILGenerator创建委托

C# 使用ILGenerator创建委托,c#,delegates,ilgenerator,C#,Delegates,Ilgenerator,如何使用ILGenerator.Emit(不是LambdaExpression.Compile?因为我正在尝试找到一个性能更高的解决方案)动态创建一个委托,该委托使用未知MethodInfo对未知目标调用未知参数 也许你看起来像这样? 如果“未知”是指任何: using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; namespace Platform.Ref

如何使用ILGenerator.Emit(不是LambdaExpression.Compile?因为我正在尝试找到一个性能更高的解决方案)动态创建一个委托,该委托使用未知MethodInfo对未知目标调用未知参数


也许你看起来像这样? 如果“未知”是指任何:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;

namespace Platform.Reflection
{
    public static class DelegateHelpers
    {
        public static TDelegate CompileOrDefault<TDelegate>(Action<ILGenerator> emitCode)
            where TDelegate : Delegate
        {
            var @delegate = default(TDelegate);
            try
            {
                var delegateType = typeof(TDelegate);
                var invoke = delegateType.GetMethod("Invoke");
                var returnType = invoke.ReturnType;
                var parameterTypes = invoke.GetParameters().Select(s => s.ParameterType).ToArray();
                var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), returnType, parameterTypes);
                var generator = dynamicMethod.GetILGenerator();
                emitCode(generator);
                @delegate = (TDelegate)dynamicMethod.CreateDelegate(delegateType);
            }
            catch (Exception exception)
            {
                // ignore
            }
            return @delegate;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Reflection.Emit;
命名空间平台.反射
{
公共静态类委托帮助器
{
公共静态TDelegate CompileOrderFault(操作代码)
其中TDelegate:委托
{
var@delegate=默认值(TDelegate);
尝试
{
var delegateType=类型(TDelegate);
var invoke=delegateType.GetMethod(“invoke”);
var returnType=invoke.returnType;
var parameterTypes=invoke.GetParameters().Select(s=>s.ParameterType.ToArray();
var dynamicMethod=newdynamicmethod(Guid.NewGuid().ToString(),returnType,parameterTypes);
var generator=dynamicMethod.GetILGenerator();
发射代码(发生器);
@delegate=(TDelegate)dynamicMethod.CreateDelegate(delegateType);
}
捕获(异常)
{
//忽略
}
return@delegate;
}
}
}

或者,您可以只参考(版本0.1.0或更高版本)NuGet软件包。并使用Platform.Reflection.DelegateHelpers。

ILGenerator.Emit可能不会比LambdaExpression.Compile快多少。后者甚至可以优化效率低下的AST。简单的方法是使用反射,我可以问一下,您想使用IL是因为性能,还是为什么要使用如此低级别的代码?@Lucastzesniewski好的,谢谢。但是编译是非常昂贵的,你能推荐一个更好的替代方案吗?@Jeremythonpson它的性能。我正在尝试寻找一个更高性能的编译替代方案,但似乎IL不会更快。也许可以尝试CallByName的性能,它仅在vb.net中可用,除非您引用Microsoft.Interactive DLL。只是想尝试一下。。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;

namespace Platform.Reflection
{
    public static class DelegateHelpers
    {
        public static TDelegate CompileOrDefault<TDelegate>(Action<ILGenerator> emitCode)
            where TDelegate : Delegate
        {
            var @delegate = default(TDelegate);
            try
            {
                var delegateType = typeof(TDelegate);
                var invoke = delegateType.GetMethod("Invoke");
                var returnType = invoke.ReturnType;
                var parameterTypes = invoke.GetParameters().Select(s => s.ParameterType).ToArray();
                var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), returnType, parameterTypes);
                var generator = dynamicMethod.GetILGenerator();
                emitCode(generator);
                @delegate = (TDelegate)dynamicMethod.CreateDelegate(delegateType);
            }
            catch (Exception exception)
            {
                // ignore
            }
            return @delegate;
        }
    }
}