【发布时间】:2008-12-22 07:21:28
【问题描述】:
当我尝试将Object obj 转换为类型T 时,如果无法转换,则说明有问题。
在我投射对象后,我将寻找使用投射对象的工作。
与其说我将在哪里使用该对象,不如说我希望在我将要转换它的地方得到一个异常。
从这个意义上说,使用DirectCast而不是TryCast更好吗?
还是我错过了使用TryCast 的其他意义?
【问题讨论】:
当我尝试将Object obj 转换为类型T 时,如果无法转换,则说明有问题。
在我投射对象后,我将寻找使用投射对象的工作。
与其说我将在哪里使用该对象,不如说我希望在我将要转换它的地方得到一个异常。
从这个意义上说,使用DirectCast而不是TryCast更好吗?
还是我错过了使用TryCast 的其他意义?
【问题讨论】:
(对于 C# 开发人员,TryCast 类似于“as”,DirectCast 相当于正常转换。正如 Mike 在 cmets 中指出的那样,“as”适用于可空值类型,但 TryCast 不't。)
如果该值确实应该是 T,那么 DirectCast 确实是正确的方法 - 它会快速失败,并出现适当的错误。
TryCast 适用于目标是“错误”类型是合法的。例如,要获取容器中的所有 Button 控件,您可以通过控件集合并 try 将每个控件强制转换为 Button。如果它有效,你就用它做点什么——如果它不起作用,你就继续。 (使用 LINQ,您可以为此目的使用 OfType,但您明白我的意思......)
根据我的经验,直接转换比 TryCast 更合适 - 尽管使用泛型我发现自己转换的频率比以前少了很多。
【讨论】:
两者之间的唯一区别是,TryCast 会在失败时返回 null,而DirectCast 会抛出异常。
这些对您如何处理程序有影响。如果不正确的转换(例如,用于用户输入的文本输入框被转换为数字类型)的可能性很高,我个人更喜欢不必抛出异常。
【讨论】:
我认为其他人已经提到了您应该和不应该执行“安全强制转换”的时间(在这种情况下,您可以确保强制转换成功,然后再冒异常风险)。如果您的程序确实需要执行安全转换,那么 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 中)强制转换在调试构建中成功并运行详尽的单元测试以证明您的实现遵循您的设计。
通过验证和测试您的设计,您可以执行直接投射,因为知道它永远不会失败。
【讨论】: