问题 TryCast在DirectCast工作的地方失败(.NET 4.0)


我发现.NET 4.0 / VS 2010中TryCast的这种行为相当令人困惑。

在我的理解中,TryCast的工作方式与DirectCast类似,但如果无法进行强制转换,则会返回Nothing而不是抛出异常。

VS 2010 / .NET 4

?TryCast(CType(1, Object), String)
Nothing
?DirectCast(CType(1, Object), String)
"1"

VS 2008 / .NET 3.5

?TryCast(CType(1, Object), String)
Nothing
?DirectCast(CType(1, Object), String)
Cannot convert to 'String'.

.NET 3.5的结果与我认为的TryCast的结果一致......但.NET不是。

有人可以指出我在.NET 4中将对象安全地转换为String的最佳方向吗?


7096
2017-08-19 15:44


起源



答案:


基于您的代码示例 ? 我猜你正在使用即时窗口来正确执行测试?这种方法的问题在于,即时窗口是解释而不是实际评估。这使得它容易受到细微的角落错误的影响,这确实是其中之一。

如果您获取示例代码并将其添加到简单的VB.Net控制台应用程序,您将发现2010行为与2008行为相同(抛出异常)。

编辑

为什么这种倒退会发生?在2010年,我完全重写了VB EE调试引擎(表达式评估程序)。我继承的旧代码库太昂贵了,无法维护。到了为引擎添加新功能的代价更高,从头开始用包含新功能的更好架构重写它。

如前所述,调试评估不仅仅是代码执行的解释。它强制在EE和CLR / Compiler之间复制一些算法。发生重复的一个领域是构建逻辑。无法要求CLR调试器转换调试时对象,EE负责确定指定的语言是否确实有效。

旧的EE构建逻辑有许多错误(特别是在泛型和数组领域)。较新的基础设施与CLR指南非常接近。但是你永远不会有100%的平价,因为它会禁止在EE中使用非常有用的表达式(我将来可能会写一篇博文)。但对于大多数情况,行为成立。

在这个特定的例子中,我添加了一个微妙的bug,它允许DirectCast输入一个值 Object 使用VB的运行时转换运算符与仅允许CLR转换的指定行为。因此,这种转换在失败的地方成功。


16
2017-08-19 15:52



我刚刚确认了你的建议。 DirectCast()确实在实际评估中运行时抛出异常。谢谢你的澄清! - motto
如果你能解释究竟发生了什么,那将是非常好的。 - SLaks
@SLaks,添加了一个快速解释。 - JaredPar
+1引人入胜...谢谢。 - SLaks


答案:


基于您的代码示例 ? 我猜你正在使用即时窗口来正确执行测试?这种方法的问题在于,即时窗口是解释而不是实际评估。这使得它容易受到细微的角落错误的影响,这确实是其中之一。

如果您获取示例代码并将其添加到简单的VB.Net控制台应用程序,您将发现2010行为与2008行为相同(抛出异常)。

编辑

为什么这种倒退会发生?在2010年,我完全重写了VB EE调试引擎(表达式评估程序)。我继承的旧代码库太昂贵了,无法维护。到了为引擎添加新功能的代价更高,从头开始用包含新功能的更好架构重写它。

如前所述,调试评估不仅仅是代码执行的解释。它强制在EE和CLR / Compiler之间复制一些算法。发生重复的一个领域是构建逻辑。无法要求CLR调试器转换调试时对象,EE负责确定指定的语言是否确实有效。

旧的EE构建逻辑有许多错误(特别是在泛型和数组领域)。较新的基础设施与CLR指南非常接近。但是你永远不会有100%的平价,因为它会禁止在EE中使用非常有用的表达式(我将来可能会写一篇博文)。但对于大多数情况,行为成立。

在这个特定的例子中,我添加了一个微妙的bug,它允许DirectCast输入一个值 Object 使用VB的运行时转换运算符与仅允许CLR转换的指定行为。因此,这种转换在失败的地方成功。


16
2017-08-19 15:52



我刚刚确认了你的建议。 DirectCast()确实在实际评估中运行时抛出异常。谢谢你的澄清! - motto
如果你能解释究竟发生了什么,那将是非常好的。 - SLaks
@SLaks,添加了一个快速解释。 - JaredPar
+1引人入胜...谢谢。 - SLaks