dlr是.net framework 4.0引入的动态语言运行时基础设施,为dynamic类型、表达式树编译和动态绑定提供底层支持;它不是语言,而是ironpython/ironruby等语言实现所依赖的引擎。

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类型?确认已安装IronPythonNuGet 包(注意:.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 则早已掉队。










