在运行时动态地创建一个功能(Creating a function dynamically at r

2019-06-24 22:43发布

它可能甚至是不可能做到这一点,但我会问反正。 是否有可能创建接收串的函数,然后使用它作为右侧参数用于进行到在lambda使用运算符(=>)?

其实,我想要做的是能够在运行时重新定义特定类的具体方法。 我想记下该程序运行并将其连接到一个委托的功能。 可能吗?

Answer 1:

要做到这一点,最简单的方法是,第三文化孩子可能建议DLINQ。

最快的(我相信,在3.5)是创建一个DynamicMethod的 。 它也是最可怕的方法为好。 你基本上建立使用IL的方法,其中有大约相同的感觉在机器语言编写代码。

我需要做的这动态附加事件处理程序在某些事情或其他(好,我并不需要做的,我只是想单元测试活动更容易)。 这似乎有点在当时令人望而生畏,因为我不知道IL废话,但我想出了一个简单的方法来做到这一点。

你要做的就是创建一个方法,你想要做什么。 越紧越好。 我会提供一个例子,如果我能找出你想要做什么。 你写在一类这个方法的DLL项目中,并在释放模式编译。 然后,你打开在反射器的DLL和拆卸你的方法。 反射给你的,你想拆机什么语言的选项 - 选择IL。 你现在有你需要添加到您的动态方法的准确调用。 只要按照MSDN上的例子,切换出的例子的IL您反映这些方法的代码。

动态方法,一旦构建,调用在大约相同的速度编译的方法(见一个测试,动态的方法可以在20毫秒〜反射哪里了200ms以上被称为)。



Answer 2:

您有几种方法如何做到这一点:

  • 动态创建lambda表达式(看动态LINQ:第1部分 )
  • 动态创建的CodeDOM模型,并在运行时编译(看CodeDom.Compiler命名空间
  • 动态地创建C#/ VB.NET源代码和在运行时对其进行编译(看CSharpCodeProvider和VBCodeProvider班)
  • 动态创建的对象模型,它可以做同样的事情,如方法(看Strategy设计模式


Answer 3:

你的问题是不太清楚,但你肯定可以使用表达式树在执行时动态创建的代表。 (有做如CodeDOM的其他方式,但表达式树是更加便利,如果他们做了一切你所需要的。但是有是你可以做什么显著的限制。)

它往往更容易,虽然使用lambda表达式与一些捕获的变量。

例如,要创建一个函数,将指定金额添加到任何整数,你可以写:

static Func<int, int> CreateAdder(int amountToAdd)
{
    return x => x + amountToAdd;
}

...
var adder = CreateAdder(10);
Console.WriteLine(adder(5)); // Prints 15

如果这没有帮助,请澄清你的问题。



Answer 4:

这并不是说我建议这个比其他更好的选择,但有7 方法和多数民众使用AssemblyBuilderModuleBuilderTypeBuilderMethodBuilderSystem.Reflection.Emit命名空间中创建一个动态组装。 这是相同的类似巫术的使用DynamicMethod

例如,你可以使用这些来,在运行时创建一个类型的代理类,并覆盖上这种类型的虚拟方法。

为了让你开始在这里是一些代码...

using System;
using System.Reflection;
using System.Reflection.Emit;

var myAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(
        new AssemblyName("Test"), AssemblyBuilderAccess.RunAndSave);
var myModule = myAssembly.DefineDynamicModule("Test.dll");
var myType = myModule.DefineType("ProxyType", TypeAttributes.Public | TypeAttributes.Class,
                        typeof(TypeToSeverelyModifyInAnUglyWayButItsNecessary));
var myMethod = myType.DefineMethod("MethodNameToOverride", 
                        MethodAttributes.HideBySig | MethodAttributes.Public,
                        typeof(void),Type.EmptyTypes);
var myIlGenerator = myMethod.GetILGenerator();
myIlGenerator.Emit(OpCodes.Ret);
var type = myType.CreateType();


Answer 5:

如果声明方法虚拟,你也许可以使用城堡的DynamicProxy代替动态生成的(与其他答案的方法之一),在运行时实现:

城堡DynamicProxy是在运行时动态生成轻量级.NET代理库。 代理对象允许在不修改类的代码被截取到对象的成员的呼叫。 类和接口可以代理,但只有虚拟成员可以被拦截。



Answer 6:

在你的问题第二段表明,真的是你可能是什么之后是简单的IOC (控制反转)

相反,声明你的类的实例,你声明一个接口的实例,并根据您选择的任何条件的,可以使用特定的覆盖类与它的正确方法。 希望是有道理的。



Answer 7:

你应该检查,看看是否你的问题可以用简单的多态性首先解决。 除非你定义抽象的互操作性,以另一种语言或编辑编译器,试图在运行时更改的方法可能是错误的解决问题的办法。



文章来源: Creating a function dynamically at run-time