当我尝试转换Object obj
为 TypeT
时,如果无法转换,则有问题。
在我投射对象之后,我将寻找使用投射对象的工作。
相反,我希望在我将要投射它的地方得到一个异常,而不是说我将在哪里使用该对象。
DirectCast
从这个意义上说,使用而不是更好TryCast
?还是我错过了使用的其他一些意义TryCast
?
(对于 C# 开发人员,TryCast
类似于“as”,DirectCast
相当于正常的强制转换。正如 Mike 在评论中指出的那样,“as”适用于可为空的值类型,但TryCast
不是。)
如果该值确实应该是 a T
,那么DirectCast
确实是正确的方法-它会快速失败,并带有适当的错误。
TryCast
当目标是“错误”类型是合法的时是合适的。例如,要获取容器中的所有 Button 控件,您可以遍历控件集合并尝试将每个控件强制转换为 Button。如果它有效,你就用它做点什么——如果它不起作用,你就继续。(使用 LINQ,您可以仅用OfType
于此目的,但您明白我的意思......)
以我的经验,直接铸造比TryCast
使用泛型更合适——尽管我发现自己铸造的频率比以前少了很多。
两者之间的唯一区别是,TryCast
如果失败,a 将返回 null,而 aDirectCast
将抛出异常。
这些对你如何处理你的程序有影响。如果不正确的转换(例如,将用户输入的文本输入框转换为数字类型)的可能性很高,我个人更喜欢不必抛出异常。
我认为其他人已经提到了你应该和不应该执行“安全强制转换”的时间(在这种情况下,你可以确保在冒着异常风险之前强制转换成功)。如果您的程序确实需要执行安全转换,那么该TryCast
方法可以为您和程序节省一些工作。
直到今天我才知道这个TryCast()
函数,我觉得使用安全铸造的“坏”方法就像个傻瓜。
如果您不了解该TryCast()
功能,那么您最终可能会得到以下结果:
'' wasteful, the TypeOf and DirectCast calls are redundant
If TypeOf obj Is SomeClass Then
someObj = DirectCast(obj, SomeClass)
'' More code
End If
问题是这种方法实际上执行了两次强制转换(从技术上讲,我认为它们实际上是类型检查)。使用TryCast
并检查结果是否为 Nothing 消除了第二次演员表并节省了不必要的工作。
'' efficient, only one cast is ever performed and there are no InvalidCastExceptions thrown
someObj = TryCast(obj, SomeClass)
If someObj IsNot Nothing Then
'' More code
End If
遵循此模式可以避免处理昂贵的异常,并有效地转换为正确的类型。
如果您的设计要求传递给您的对象必须是 T 类型,则断言(如在 Debug.Assert 中)该转换在调试构建中成功并运行详尽的单元测试以证明您的实现遵循您的设计。
随着您的设计经过验证和测试,您可以执行直接铸造,因为它知道它永远不会失败。