为什么“动态”的实现需要特定于语言的运行时组件?

3

使用 dynamic 功能需要 Microsoft.CSharp。
我了解程序集中有绑定器、评估器和帮助程序。
但为什么它必须是特定于语言的?
为什么是 Microsoft.CSharp 而不是 Microsoft.Dynamic 或 System.Dynamic?

请解释一下。
假设我们有 d.x,其中 ddynamic
C# 编译器
1. 应用 C# 语言规则
2. 得到 "属性或字段访问"
3. 发出 (形象地) Binder.GetPropertyOrField(d, "x")
现在,被要求引用 Microsoft.CSharp 可能会使人们认为,语言无关的绑定器无法处理此情况,并且只有 C#-only 的某些东西通过编译并需要特殊库。
编译器今天过得不太好?


4
基本上,正是C#专用的运行时编译器部分有助于编译与System.Dynamic相关的代码。 - CodeCaster
@CodeCaster 当然,当然。但是为什么要将某些内容留在“未编译”状态,需要特定于语言的运行时编译器部分呢?你有例子吗? - Leonid
2个回答

2
一种我能想到的原因是,Visual Basic.NET 从一开始就具有迟绑定,主要是围绕它如何与 COM IDispatch 接口互操作 - 因此,如果他们想要一个语言不可知的绑定器,他们将不得不采用 Visual Basic 规则 - 其中包括成员查找仅适用于Public成员。
显然,C# 设计者不想那么严格。您可以通过动态引用从 C# 调用此类的 DoStuff 方法:
public class Class1
{
    internal void DoStuff()
    {
        Console.WriteLine("Hello");
    }
}

尝试通过Visual Basic的Object调用相同内容会在运行时引发MissingMemberException。因此,由于C#设计者不是第一个到达晚期绑定聚会的人,他们可以选择跟随Visual Basic的领导,或者他们可以说“每种语言都有自己的规则”——他们选择了后者。

拥有自己的规则是可以理解的,但它并不会立即自动地将我们(至少是我)带到另一个程序集。此外,我从你的回答中得到的印象是,VB特定的绑定器(在某个时候是唯一的)驻留在核心库中。是这样吗? - Leonid

2
对于你的第一个问题,它是与语言相关的,因为必须如此。
在C#中,如果你调用一个带有太多参数的方法,会出现错误。而在Javascript中,额外的参数只是被忽略了。在C#中,如果你访问一个不存在的成员,会出现错误,而在Javascript中,则会得到undefined。即使你发现了所有这些不同的特性集,并将其全部放入System.Core中,下一个月的语言潮流肯定会有一些超级棒的功能,它不支持。更好的方式是保持灵活性。
在.NET Core中,有一些通用代码,位于System.Dynamic和System.Runtime.CompilerServices命名空间下。但并不是所有的都可以通用。
至于你的第二个问题,消除"特殊的C#库"的需要当然可以通过内联转换这些与语言相关的行为来实现,但为什么要这样做呢?那只会不必要地增加你的IL代码大小。这与你每次需要读取数字时都不编写自己的Int32.Parse的原因相同。

谢谢,我明白了你的意思。程序可能足够复杂,以至于从中提取行为并将其放入单独的程序集中会带来很多好处。除了可移植性和向后兼容性问题之外,没有理由不将其托管在框架内。 - Leonid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接