2010-11-10 14 views
3

Один из моих младших программистов создал синглтон, но он действует странно:Почему это однопользовательское поведение происходит?

Я знаю, что вы не должны обращаться к объекту, подобному этому, но вот как они это сделали, и я не могу объяснить, почему это возникающий - после вызова экземпляра delete я помещаю точку останова в строку после, и я все еще могу получить доступ к объекту someObject и его свойствам. Такой подход имеет смысл, поскольку ваш доступ к ссылке объекта mySingleton, а не myInstance, ... как вы можете видеть, я не могу объяснить это ясно, может ли кто-нибудь помочь?

например.

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! 

Вот псевдопользователей код для одноточечного:

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 

Лично я не пишу одиночек, как это - у меня есть экземпляр объекта в качестве отдельного класса. но каждый по своему усмотрению.

+1

Важный момент: что '_myInstance' использование * не * одноэлементно, а не поточно-. В частности, если это ASP.NET (или любая другая высокопоточная среда), у вас будет хаос. –

+0

Я забыл упомянуть - я ожидал бы исключение null ref после вызова экземпляра delete ... –

+0

@Marc - да, я знаю, я упростил код –

ответ

1

В общем, в .NET вы никогда не сможете явным образом/детерминистически установить объект в ничто. Вы можете установить только ссылки на Nothing, а затем разрешить сборщику мусора очистить его. Как уже было сказано, в вашем исходном коде вы фактически сохранили ссылку на него, назначив ему x.

В общем случае установка объекта в Nothing или null не предлагается, поскольку объект имеет право на сбор мусора после последней ссылки; время выполнения замечает это. Например, если у вас есть такой код:

Dim anObject as new MyObject 

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

Set anObject = Nothing 
[2] 

Если вы не установили объект в настоящее время, было бы иметь право на получение коллекции в любое время после точки [1]. Если вы это сделаете, это не будет иметь право до пункта [2]. Если ваш метод занимает много времени, это может стать важным.

Подробнее:

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

6

Это потому, что вы удалили только ссылку MySingleton._myInstance.

x все еще имеет ссылку на этот объект.

Edit:
Для уточнения:

это как:

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

+1, потому что я собирался это сказать. – Bobby

+0

, установив _myInstance на ничего, не должны ли все ссылки на этот ссылочный объект теперь ничего не указывать? –

+0

Какое ваше высказывание, которое я знаю, истинно, я не понимаю, что если я должен изменить a.property на что-то, b.property автоматически будет равным этому, поскольку это ссылочный тип, указывающий на объект a ... почему имя не применяется для установки объекта в ничто? –

4

Первая строка получает ссылку на ваш одноэлементных, и эта ссылка будет оставаться в силе до тех пор, пока объект не будет мусора , Однако, пока есть ссылки на объект, он не будет собирать мусор, поэтому вы будете продолжать ссылаться на действительный объект, пока вы явно не назначите x другому.

+0

Это имеет смысл, я только что заметил, что он хранит синглтон в качестве члена varible –