2010-08-12 3 views
2

Скажем, у меня есть следующий класс ...Что происходит с ссылочной переменной, если удаленный объект ссылки удаляется?

Class1 
{ 
    private ArrayList myList; 

    private Class1 
    { 
    // Here fill myList with a bunch of Foo objects. 
    } 

    public ArrayList GetList() 
    { 
    return myList; 
    } 
} 

Тогда говорят, в каком-то другом классе у вас есть следующий код ...

Class1 myClass = new Class1(); 
Foo myFavoriteFoo = myClass.GetList()[0] As Foo; 

Теперь myFavoriteFoo на самом деле ссылка на Foo, что существует в arraylist в Class1. Что произойдет, если что-то внутри класса 1 удалит этот конкретный Foo из класса или избавится от него? Будет ли myFavoriteFoo немедленно = null? Я предполагаю, что если бы я попытался получить доступ к Foo.SomeMethod(), я бы просто получил исключение, например «Ссылка на объект не установлена ​​в экземпляр объекта» ...

ответ

2

Ответ заключается в том, что этого не может быть.

dotNet предлагает тип безопасности: ссылка всегда указывает на действительный экземпляр или имеет значение null, никаких других параметров. Вот почему в dotNet нет ручного управления памятью (без удаления).

Так что если ваш код держит ссылку на объект где-то, то эта ссылка блокирует его из коллекции мусора.

И Dispose() что-то еще, у него есть ничего, чтобы сделать с памятью объект занимает. Dispose() - это очистка для (неуправляемых) ресурсов, и обычно объект устанавливает внутреннее состояние «недействительным».

+0

Фактически, если это правильно реализовано для неуправляемых ресурсов, тогда сборщик мусора автоматически освобождает память, выделенную управляемому объекту, когда этот объект больше не используется. 'Http://msdn.microsoft.com/en-us/library/ system.idisposable.aspx. Важно отметить, что можно реализовать «IDisposable», но на самом деле не может использовать неуправляемые ресурсы. – TheCloudlessSky

+0

@TheCloud: GC автоматически освобождает _all_ управляемые объекты, не связанные с неуправляемыми ресурсами. –

0

Если установить объект ПОЛУЧИТЬ к нулю послеmyFavoriteFoo имеет ссылку на него, myFavoriteFoo все еще держит ссылку. Если Foo правильно реализует IDisposable, вы получите исключение, если попытаетесь получить к нему доступ после вызова Dispose() объекта.

0

Объекты-ссылки не будут удалены, пока есть ссылки, указывающие на них (за некоторыми исключениями вам не о чем беспокоиться). Когда исходная ссылка выходит за пределы области видимости, другая ссылка все равно укажет на ваш объект, и объект останется в живых. После того, как вы сбросите вторую ссылку (установив ее в значение null, присвоив ей другое значение или у нее закончится область действия), GC может ее собрать (но не гарантируется немедленно).

0

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

Истинное поведение заключается в том, что если кто-то удаляет объект из списка, это не означает, что объект удаляется из памяти. Сборщик мусора проверяет, имеет ли объект ссылки на него, а в вашем случае myFavoriteFoo содержит ссылку, поэтому GC не удалит объект.

В случае удаления - на C# нет возможности принудительно удалить объект вручную, даже если вы вызываете dispose или destructor, объект проверяется сборщиком мусора, и объект будет удален ТОЛЬКО, если он имеет 0 ссылок на Это.

Это верно для регулярных ссылок. Также в .Net есть класс WeakReference, который переопределяет правила для регулярной ссылки.

0

Class1 не является собственностью ArrayList. Он просто ссылается на него. Оба myFavoriteFoo и myClass.myList: ссылки в ArrayList.

Таким образом, весь класс может установить его собственный ссылка на null. Но это не удаляет ArrayList. Это просто означает, что на него есть меньше ссылок.

Но до тех пор, пока существует хотя бы одна ссылка, ArrayList не удаляется. Таким образом, ситуация, о которой вы описываете, никогда не может произойти.

0

myFavoriteFoo - это другое (кроме одного из массива) ссылка на ваш объект. Пока ссылка активна, объект не будет собираться с мусором. Поэтому удаление элемента из массива в Class1 не влияет на ссылку myFavoriteFoo - оно остается в живых. С другой стороны, если объект расположен (через вызов dispose/close) внутри Class1, тогда вы можете получить сообщение об ошибке, если попытаетесь использовать его метод - ошибка будет похожа на тот объект, который уже был удален.

Смежные вопросы