【问题标题】:What does "late-bound access to the destination object" mean?“对目标对象的后期绑定访问”是什么意思?
【发布时间】:2019-12-22 23:13:53
【问题描述】:
【问题讨论】:
标签:
c#
.net
concurrency
late-binding
interlocked
【解决方案1】:
canton7 的回答是正确的,感谢您的支持。我想补充几点。
这句话,就像 .NET 文档中经常出现的情况一样,都选择了构建奇怪的单词用法,并且完全没有抓住重点。对我来说,突出的糟糕的单词选择不是“后期绑定”,它只是没有抓住重点。真正糟糕的词选择是使用“目标对象”来表示变量。变量不是对象,就像你的袜子抽屉是一双袜子一样。变量包含对对象的引用,就像袜子抽屉包含袜子一样,这两件事不应该混淆。
正如您所注意到的,偏爱T 版本的原因与后期绑定无关。更喜欢T 版本的原因是C# 不允许在ref 参数上进行变体转换。如果您有 Turtle 类型的变量 shelly,则不能将 ref shelly 传递给采用 ref object 的方法,因为该方法可以将 Tiger 写入 ref object。
那么在shelly 上使用Object-taking 重载的逻辑后果是什么?只有两种可能:
- 我们将
shelly的值复制到Object类型的第二个变量,进行交换,然后将新值复制回来,现在我们的操作不再是原子的,这就是重点调用联锁交换。
- 我们将
shelly 更改为Object 类型,现在我们处于一个非静态类型且因此容易出错的世界中,我们无法确定shelly 仍然包含对@ 的引用987654337@.
由于这两种选择都很糟糕,您应该使用通用版本因为它允许别名变量在整个操作过程中具有正确的类型。
【解决方案2】:
Interlocked.Exchange(object, object) 的等效注释是:
从 .NET Framework 2.0 开始,Exchange<T>(T, T) 方法重载为引用类型提供了一种类型安全的替代方案。我们建议您调用它而不是这个重载。
虽然我以前没有听说过以这种方式使用它,但我认为“后期绑定”只是意味着“非类型安全”,因为您需要将 object 转换为您的具体类型(在运行时) 在使用之前。
与虚拟方法分派一样,“后期绑定”通常也指反射,因为要调用的确切方法要到运行时才能知道。
引用Eric Lippert:
基本上,“早期绑定”是指“绑定分析由编译器执行并嵌入到生成的程序中”;如果绑定失败,则程序不会运行,因为编译器没有进入代码生成阶段。 “后期绑定”是指“绑定的某些方面将由运行时执行”,因此绑定失败将表现为运行时失败
(强调我的)。在这个相当松散的定义下,将object 转换为具体类型,然后对其调用方法可以被视为“后期绑定”,因为绑定的一个元素在运行时执行并且可能在运行时失败。