使用 DLR 运行使用 CompileAssemblyFromSource 生成的代码?

2023-11-21

对此进行后续跟进很好的答案,我想知道 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();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 DLR 运行使用 CompileAssemblyFromSource 生成的代码? 的相关文章

随机推荐

  • ReactJS - FCM 无法在 safari 浏览器中工作[重复]

    这个问题在这里已经有答案了 我正在尝试在我的 ReactJS 应用程序中实现 FCM 推送通知 它在 chrome 和 firefox 浏览器中完美运行 但在 safari 浏览器中遇到问题 FirebaseError 消息传递 此浏览器不
  • 应用程序提供的字体列表 (iOS)

    有谁知道如何从 Xcode 中 info plist 文件中的 应用程序提供的字体 键获取自定义字体列表 谢谢 以下代码从 Info plist 中读取自定义字体文件列表 并从字体文件中提取完整的字体名称 部分代码复制自https stac
  • 在 .NET 应用程序中使用 ApacheFOP v1.0

    有人成功地将 Apache FOP v1 0 库编译为 NET DLL 吗 我正在使用位于以下位置的 IKVM 语法 http onjava com pub a onjava 2004 08 18 ikvm html 然而 编译后的DLL似
  • Karma 错误 - 未知提供商:$$asyncCallbackProvider

    尝试通过 grunt 运行我的业力测试 但出现错误 Error injector modulerr Failed to instantiate module ngMock due to Error injector unpr Unknown
  • 如何动态改变ImageView高度

    我有一个用于 ListView 单元格的简单线性布局 它有一个图像视图 图像将从互联网下载 因此尺寸可以不同 但是 我想将imageview的宽度设置为fill parent 这是固定的 并在运行时动态改变图像高度 设置图像高度的规则 如果
  • 在调用保存字符串 ID 之前,必须手动分配此类的 ID

    已经阅读了很多关于同一问题的问题 但我仍然无法解决这个问题 我需要有一个String我的数据库上的主键 import javax persistence Entity import javax persistence Id Entity p
  • 显示 system.data.datarowview 的组合框数据绑定

    我将组合框与数据源 显示成员 值成员绑定 它在我的电脑上运行良好 但在客户端电脑上无法运行 以下是我的源代码 cbxAlloyBinding 方法是从 UserControl 的构造函数中调用的 private void cbxAlloyB
  • 从 shell 脚本读取 python 脚本中带空格的参数

    运行 python 脚本时如何读取带空格的参数 UPDATE 看来我的问题是我通过 shell 脚本调用 python 脚本 这有效 gt python script py firstParam file with spaces txt o
  • 如何检测图像何时失焦?

    有时 我们的光学检测系统会失焦 导致测量结果无意义 我的任务是开发一个 失焦 探测器 用于驱动相机系统的 Z 轴 我可用的图像是 bmp 我正在寻找方法和算法来研究 例如 我应该隔离特征并测量一致性 还是可以使用边缘检测 This is t
  • '^' 在 C#(枚举)中起什么作用?

    我正在阅读一些第 3 方代码 发现了以下内容 x Flags x Flags Flags Hidden 它有什么作用 我使用了 和 对于带有枚举的按位 与 和 或 但这是我第一次看到该符号 是 C 中的按位异或运算符 编辑 如果 a 为真且
  • T-SQL CASE 子句:如何指定 WHEN NULL

    我写了一个类似这样的T SQL语句 原来的看起来不同 但我想在这里给出一个简单的例子 SELECT first name CASE last name WHEN null THEN Max ELSE Peter END AS Name FR
  • 调整 XORShift 生成器以返回最大值内的数字

    我需要生成最大范围内的随机整数 自从性能至关重要 我决定使用 XORShift 生成器而不是 Java 的 Random 类 long seed System nanoTime seed seed lt lt 21 seed seed gt
  • 从版本 5.0.3 开始,在 mysql 表的小数字段中存储负数

    我的表中很少有带有小数类型金额列的字段 此列将包含存款金额 正值 或取款金额 负值 我将正值存储为 120 将负值存储为 50 我对该列求和并得到了预期的结果 Mysql版本是 5 1 33 community 当我检查有关十进制的 mys
  • 在 TextView 中使用 SpannableStringBuilder 的段落间距

    正如问题所示 我正在研究TextView这将使用显示格式化文本SpannableStringBuilder 它有多个段落 我想知道使用某些内置跨度设置段落之间的间距的最简单 或至少最不复杂 的方法是什么 这可能吗 或者我需要为此构建一个自定
  • 类型错误:__init__() 需要 3 个位置参数,但给出了 4 个

    这些是我的课程的代码 class Employee def init self name gender self name name self gender gender class Salary def jump self name sa
  • UTF-8 和 UTF-16 之间有很大区别吗

    我调用一个 Web 服务 它返回一个具有 UTF 8 编码的响应 xml 我用java检查了这一点getAllHeaders method 现在 在我的 java 代码中 我获取该响应 然后对其进行一些处理 然后 将其传递给不同的服务 现在
  • Visual Studio 2010 主题,更改参数帮助背景颜色

    最近我在 Visual Studio 2010 中安装了电动工具扩展它工作得很好 但是我的文本着色主题有问题 黄昏 以及扩展的彩色参数功能 由于主题文本前景色为灰色 当 Power Tools Extensions 使用我的文本颜色显示参数
  • Chrome 扩展程序弹出窗口中单击时的 JavaScript 警报立即消失

    我正在开发一个 Chrome 扩展程序 并希望在用户单击某些元素时使用 Prompt 获取用户的输入 不幸的是 由于某种原因 当作为 onclick 或在 jQuery something click function 中调用时 我无法让p
  • 使用 JavaScript 使用 HmacSHA256 正确签署字符串

    在用于身份验证的 Houndify API 文档中 您有以下内容块 验证请求的示例 假设我们有以下信息 UserID ae06fcd3 6447 4356 afaa 813aa4f2ba41 RequestID 70aa7c25 c74f
  • 使用 DLR 运行使用 CompileAssemblyFromSource 生成的代码?

    对此进行后续跟进很好的答案 我想知道 DLR 是否使用dynamic关键字可以允许以不太冗长的方式为生成的程序集编写代码 例如 上述答案的代码可以 using Microsoft CSharp CSharpCodeProvider foo