为什么要在Finally块中将对象设置为Nothing?

3
在这段VB.NET代码中:
Dim o as SomeClass
Try
   o = new SomeClass
   'call some method on o here
Catch(...)
   ...
Finally
   o = Nothing
End Try

为什么需要将'o'设置为'Nothing'?如果在“Finally”块中不将其设置为“Nothing”,会发生什么?我认为,如果不将其设置为“Nothing”,那么也是可以的,因为该对象将被标记为垃圾回收。

如果SomeClass有一个.Dispose方法,你应该使用它:https://dev59.com/pXVD5IYBdhLWcg3wVKEb - Andrew Morton
可能是Calling null on a class vs Dispose()的重复问题。(忽略最高评分答案是C#的事实。对于VB.NET来说,它完全相同。在VB.NET中将对象设置为“Nothing”是完全多余的。请注意,这与基于COM的VB版本(如VB 6)不同。) - Cody Gray
2个回答

4
如果对象在try catch外部使用是不安全的,应该这样做。例如,如果这是一个流,您会看到流被关闭,然后设置为null。但这并不总是正确的做法,但是这段代码经常被使用。
考虑以下代码。
Sub Main()
    Dim o As String
    Try
        o = "Hello"
        Console.Out.WriteLine("hi {0}", o)
    Catch ex As Exception
        ' do something here
    Finally
        o = Nothing
    End Try

    ' unable to do something here
End Sub

虽然这只是一个愚蠢的示例,但它意味着您现在无法引用o,因为它不再设置为对象的实例。这就是为什么很多人都这样做的原因。如果您在函数中,并且函数在那一点结束,那么没有必要将其设置为Nothing,因为对象超出范围,但是许多人会出于习惯将东西设置为Nothing我认为这是不正确和糟糕的代码设计


这是否意味着,作为一种惯例,我应该在使用完对象后将它们全部设置为“Nothing”? - badmaash
1
@badmaash:不需要。正如krystan所说,“只有当对象不安全时才需要使用”。大多数情况下是不需要的。 - Meta-Knight
1
任何正确设计的类,如果您在处理完后尝试使用它,都会抛出异常。将其设置为“Nothing”是多余的。我认为这是一个不好的模式,因为人们认为它实际上做了什么。它只会给您的代码增加噪音。正如您提到的,如果该类设计不良,不能在不当使用时引发异常,则应充分利用作用域。Using语句是最简单的方法,但您也可以将其包装在新函数中。 - Cody Gray

0

这是因为该对象在 try.. catch.. finally 块之外使用时不安全。无法保证其处于一致的状态,因此将其设置为 Nothing,以明确表示它不应被使用。


3
实际上不是这样的。这是VB6和COM时代的遗留问题,当设置为“Nothing”时,实际上会对对象的引用计数进行递减。 - John Saunders

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接