为什么会发生这种单身行为?

时间:2010-11-10 13:13:40

标签: .net vb.net design-patterns language-agnostic

我的一名初级程序员创建了一个单身人士,但行为奇怪:

我知道你不应该像这样访问对象,但是他们是这样做的,我无法解释为什么会发生这种情况 - 在调用删除实例之后,我在线路上放了一个断点,我仍然可以访问someObject对象及其属性。这种方式有意义,因为您访问mySingleton对象的引用,而不是myInstance,...正如您所看到的,我无法清楚地解释它,任何人都可以帮忙吗?

e.g。

    Dim x As MySingleton = MySingleton.GetInstance()

    x.someObject.int = 5
    x.someObject.str = "hello"

    Console.Out.WriteLine(x.someObject.int.ToString)
    Console.Out.WriteLine(x.someObject.str.ToString)

    MySingleton.RemoveInstance()

    Console.Out.WriteLine(x.someObject.int.ToString) //still exists!
    Console.Out.WriteLine(x.someObject.str.ToString) //still exists!

这是单身人士的Psuedo代码:

Public Class MySingleton

    Private Shared _myInstance As MySingleton

    Public someObject As New Class1

    Public Shared Function GetInstance() As MySingleton
        If _myInstance Is Nothing Then
            _myInstance = New MySingleton
        End If
        Return _myInstance

    End Function

    Public Shared Sub RemoveInstance()
        _myInstance = Nothing
    End Sub


    End Class

就我个人而言,我不会像这样编写我的单身人士 - 我将实例对象作为一个单独的类。但每个都是他们自己的。

3 个答案:

答案 0 :(得分:6)

这是因为您只删除了对象的MySingleton._myInstance引用。

x仍然引用该对象。

修改
澄清:

就像:

var A = new Class();
var B = A;
A = null;
// Here B still has that reference to the created object

答案 1 :(得分:4)

第一行获取对您的单例的引用,该引用将保持有效,直到对象被垃圾回收。但是,只要仍然存在对对象的引用,它就不会被垃圾收集 - 因此在您明确地将x指定给其他对象之前,您将继续引用有效对象。

答案 2 :(得分:1)

通常,在.NET中,您永远不能明确/确定地将对象设置为空。您只能将其引用设置为Nothing,然后允许垃圾收集器清理它。如前所述,在原始代码中,您实际上通过将其分配给x来保留对它的引用。

通常,不建议将对象设置为Nothing或null,因为对象在最后一次引用后有资格进行垃圾回收;运行时注意到这一点。例如,如果你有这样的代码:

Dim anObject as new MyObject

anObject.DoAnOperation()
[1]
... 
...
'more code
...
...

Set anObject = Nothing
[2]

如果您没有将对象设置为Nothing,则在[1]之后的任何时间都可以进行收集。如果这样做,直到第[2]点才符合条件。如果您的方法需要很长时间才能完成,那么它可能会变得很重要。

更多信息:

http://msdn.microsoft.com/en-us/library/ee787088.aspx