在此跟进出色答卷 ,我想知道如果使用DLR的dynamic
关键字可以允许生成的汇编编写代码的更简洁的方式。
例如,可以将上述答案的代码:
using (Microsoft.CSharp.CSharpCodeProvider foo =
new Microsoft.CSharp.CSharpCodeProvider())
{
var res = foo.CompileAssemblyFromSource(
new System.CodeDom.Compiler.CompilerParameters() {
GenerateInMemory = true
},
"public class FooClass { public string Execute() { return \"output!\";}}"
);
var type = res.CompiledAssembly.GetType("FooClass");
var obj = Activator.CreateInstance(type);
var output = type.GetMethod("Execute").Invoke(obj, new object[] { });
}
成为类似:
using (Microsoft.CSharp.CSharpCodeProvider foo =
new Microsoft.CSharp.CSharpCodeProvider())
{
var res = foo.CompileAssemblyFromSource(
new System.CodeDom.Compiler.CompilerParameters() {
GenerateInMemory = true
},
"public class FooClass { public string Execute() { return \"output!\";}}"
);
var type = res.CompiledAssembly.GetType("FooClass");
dynamic obj = Activator.CreateDynamicInstance(type);
var output = obj.Execute();
}
是的,你可以做到这一点,它工作得很好。 然而,在使用动态关键字更方便,它利用后期绑定,仍然是一样不安全的,在这个意义上,作为明确使用反射。 如果您的设计允许的话,那就更好了使用共享接口或基类早期绑定。 您可以通过在组装或在第三,共享程序集创建一个公开的类型做到这一点,然后从一个新的你正在编译动态向组装添加引用。 然后,在所生成的代码,可以从在参考组件共享类型继承。 例如,创建一个接口:
public interface IFoo
{
string Execute();
}
然后动态编译这样的组件:
using (Microsoft.CSharp.CSharpCodeProvider foo = new Microsoft.CSharp.CSharpCodeProvider())
{
var params = new System.CodeDom.Compiler.CompilerParameters();
params.GenerateInMemory = true;
// Add the reference to the current assembly which defines IFoo
params.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
// Implement the IFoo interface in the dynamic code
var res = foo.CompileAssemblyFromSource(params, "public class FooClass : IFoo { public string Execute() { return \"output!\";}}");
var type = res.CompiledAssembly.GetType("FooClass");
// Cast the created object to IFoo
IFoo obj = (IFoo)Activator.CreateInstance(type);
// Use the object through the IFoo interface
obj.Execute();
}
这取决于你如何的控制力动态代码,这可能会或可能不会是可能的,但是当它是,它很高兴有编译时类型检查。 例如,如果你试图执行:
IFoo obj = (IFoo)Activator.CreateInstance(type);
obj.Execcute();
这第二条线会立即编译失败,因为它是拼写错误,而使用动态关键字或反射,该行会成功编译但它会导致运行时异常。 例如,下面不会得到一个编译时错误:
dynamic obj = Activator.CreateDynamicInstance(type);
obj.Execcute();
这就是DLR设计的方案之一。 你可以用这种方式来调用动态加载的类的成员,同时避免从手动调用所有的额外打字.GetMethod()
和.Invoke()