我发现.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的最佳方向吗?
答案 0 :(得分:16)
根据您的代码示例以?
开头我猜您正在使用即时窗口来执行测试吗?这种方法的问题在于,即时窗口是解释而不是实际评估。这使得它容易受到细微的角落错误的影响,这确实是其中之一。
如果您获取示例代码并将其添加到简单的VB.Net控制台应用程序中,您将发现2010行为与2008行为相同(抛出异常)。
修改强>
为什么这种倒退会发生?在2010年,我完全重写了VB EE调试引擎(表达式评估程序)。我继承的旧代码库太昂贵了,无法维护。到了为引擎添加新功能的代价更高,从头开始用包含新功能的更好架构重写它。
如前所述,调试评估不仅仅是代码执行的解释。它强制在EE和CLR /编译器之间复制一些算法。发生重复的一个领域是在构建逻辑中。无法要求CLR调试器转换调试时对象,EE负责确定指定的语言是否确实有效。
旧的EE构建逻辑存在大量错误(特别是在泛型和数组领域)。较新的基础设施与CLR指南非常接近。但是你永远不会有100%的平价,因为它会禁止在EE中使用非常有用的表达式(我可能会在将来写一篇博文)。但对于大多数情况来说,这种行
在这个特定的实例中,我添加了一个微妙的错误,允许DirectCast的值为Object
,以使用VB的运行时转换运算符与仅允许CLR转换的指定行为。因此,这种转换在失败的地方成功。