C# 动态语言运行时DLR方法 C# DLR是如何与Python和Ruby交互的

来源:这里教程网 时间:2026-02-21 17:42:53 作者:

DLR 是什么,它不等于 IronPython 或 IronRuby

DLR(Dynamic Language Runtime)是 .NET Framework 4.0 引入的一套运行时服务,不是独立语言,而是为

dynamic
类型、表达式树编译、动态绑定提供底层支持的基础设施。它本身不“运行 Python”或“运行 Ruby”,真正做这件事的是基于 DLR 构建的语言实现——比如
IronPython
IronRuby

换句话说:DLR 是引擎,IronPython/IronRuby 是装上这个引擎的车。你不能直接用 DLR 解析

.py
文件,但可以用
ScriptEngine
(来自 IronPython)加载并执行 Python 代码。

在 C# 中调用 Python 脚本:依赖 IronPython 的 ScriptEngine

要让 C# 与 Python 交互,必须引用

IronPython.dll
Microsoft.Scripting.dll
(二者都属于 DLR 生态)。核心入口是
Python.CreateEngine()

var engine = Python.CreateEngine();
var scope = engine.CreateScope();
engine.Execute("print('Hello from Python')", scope);

常见问题包括:

立即学习“Python免费学习笔记(深入)”;

找不到
Python
类型?确认已安装
IronPython
NuGet 包(注意:.NET Core/.NET 5+ 需用
IronPython.StdLib
分离包,且部分标准库功能受限)
执行含中文路径或字符串时报编码错误?显式设置
engine.SetSearchPaths
并避免使用默认控制台编码
想从 Python 访问 C# 对象?需用
scope.SetVariable("obj", myCSharpObj)
,且该对象成员需为 public,或标记
[DynamicMemberAccess]

dynamic 与 DLR 绑定的关系:不是所有 dynamic 都走 DLR

C# 的

dynamic
变量在编译期跳过静态检查,但实际分发逻辑取决于运行时对象类型:

若对象是
ExpandoObject
或实现了
IDynamicMetaObjectProvider
(如 IronPython 的
PythonOps
返回的对象),则走 DLR 的
MetaObject
协议,支持属性/方法动态解析
若只是普通对象转成
dynamic
(如
(dynamic)new object()
),则仍走 CLR 的反射路径,性能更低,且不享受 DLR 缓存优化
DLR 会缓存绑定结果(如方法签名、属性位置),但一旦 Python 脚本修改了类结构(如 monkey patch),缓存可能失效,触发重新绑定

Ruby 交互同理,但生态支持已基本停滞

IronRuby
曾提供类似的
Ruby.CreateEngine()
,但自 2011 年后官方停止维护,.NET Core 完全不兼容。目前没有活跃的、支持现代 .NET 的 Ruby 运行时构建在 DLR 上。如果你看到“C# 调用 Ruby”,大概率是通过进程启动
ruby.exe
或使用 REST API 封装,而非真正的 DLR 集成。

DLR 本身仍在 .NET 运行时中存在(例如支撑

ExpandoObject
System.Text.Json
的动态反序列化),但它对第三方动态语言的支持,实际取决于对应语言实现是否持续跟进——而这一点,Python(IronPython)尚可维持基础功能,Ruby 则早已掉队。

相关推荐

热文推荐