【问题标题】:Why use TryCast instead of DirectCast?为什么使用 TryCast 而不是 DirectCast?
【发布时间】:2008-12-22 07:21:28
【问题描述】:

当我尝试将Object obj 转换为类型T 时,如果无法转换,则说明有问题。

在我投射对象后,我将寻找使用投射对象的工作。

与其说我将在哪里使用该对象,不如说我希望在我将要转换它的地方得到一个异常。

从这个意义上说,使用DirectCast而不是TryCast更好吗? 还是我错过了使用TryCast 的其他意义?

【问题讨论】:

    标签: vb.net casting


    【解决方案1】:

    (对于 C# 开发人员,TryCast 类似于“as”,DirectCast 相当于正常转换。正如 Mike 在 cmets 中指出的那样,“as”适用于可空值类型,但 TryCast 不't。)

    如果该值确实应该是 T,那么 DirectCast 确实是正确的方法 - 它会快速失败,并出现适当的错误。

    TryCast 适用于目标是“错误”类型是合法的。例如,要获取容器中的所有 Button 控件,您可以通过控件集合并 try 将每个控件强制转换为 Button。如果它有效,你就用它做点什么——如果它不起作用,你就继续。 (使用 LINQ,您可以为此目的使用 OfType,但您明白我的意思......)

    根据我的经验,直接转换比 TryCast 更合适 - 尽管使用泛型我发现自己转换的频率比以前少了很多。

    【讨论】:

    • 但是,TryCast 与 C# 的“as”不同。 TryCast 仅适用于引用类型,而“as”处理值类型。请参阅我关于此问题的问题 (stackoverflow.com/questions/1297297/…)
    • @Mike:您的评论听起来像是“as”处理所有值类型。它只处理 nullable 值类型。但是,是的,这是一个区别。将编辑。
    • 只要转换不缩小,使用 DirectCast 的另一个原因是“如果 DirectCast 检测到不存在继承或实现关系,则会生成编译器错误”。 msdn.microsoft.com/en-us/library/7k6y2h6x.aspx
    【解决方案2】:

    两者之间的唯一区别是,TryCast 会在失败时返回 null,而DirectCast 会抛出异常。

    这些对您如何处理程序有影响。如果不正确的转换(例如,用于用户输入的文本输入框被转换为数字类型)的可能性很高,我个人更喜欢不必抛出异常。

    【讨论】:

      【解决方案3】:

      我认为其他人已经提到了您应该和不应该执行“安全强制转换”的时间(在这种情况下,您可以确保强制转换成功,然后再冒异常风险)。如果您的程序确实需要执行安全转换,那么 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
      

      遵循这种模式可以避免处理代价高昂的异常,并有效地转换为正确的类型。

      【讨论】:

      • ...我向为我们工作的几个承包商提供了相同的建议,发现他们滥用了 TryCast()。提醒:仅在有正当理由期望对象不是目标类型时才使用 TryCast。如果 someObject 总是 SomeType 然后 DirectCast 傻瓜,如果不是,让 DirectCast 抛出异常。 TryCast() 滥用给我们留下了没有证据的错误。对象不是所需的类型,TryCast 没有引发错误,代码没有执行,也没有记录异常。
      【解决方案4】:

      如果您的设计要求传递给您的对象必须为 T 类型,则断言(如在 Debug.Assert 中)强制转换在调试构建中成功并运行详尽的单元测试以证明您的实现遵循您的设计。

      通过验证和测试您的设计,您可以执行直接投射,因为知道它永远不会失败。

      【讨论】:

        猜你喜欢
        • 2011-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-07
        • 1970-01-01
        • 1970-01-01
        • 2012-05-28
        • 2021-10-12
        相关资源
        最近更新 更多