Что происходит с переменной Reference, если указанный объект удаляется? - PullRequest
2 голосов
/ 12 августа 2010

Скажем, у меня есть следующий класс ...

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

Ответы [ 6 ]

2 голосов
/ 12 августа 2010

Ответ таков: этого не может быть.

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

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

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

0 голосов
/ 12 августа 2010

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

0 голосов
/ 12 августа 2010

Class1 не является владельцем ArrayList. Он просто содержит ссылку на него. И myFavoriteFoo, и myClass.myList являются ссылками на ArrayList.

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

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

0 голосов
/ 12 августа 2010

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

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

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

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

0 голосов
/ 12 августа 2010

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

0 голосов
/ 12 августа 2010

Если для объекта get установлено значение null после того, как myFavoriteFoo имеет ссылку на него, myFavoriteFoo по-прежнему содержит ссылку. Если Foo правильно реализует IDisposable, вы получите исключение, если попытаетесь получить к нему доступ после вызова Dispose() для объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...