﻿# V3145\. Unsafe dereference of a WeakReference target\. The object could have been garbage collected before the 'Target' property was accessed\.

Анализатор обнаружил небезопасное использование объекта типа 'WeakReference', которое может привести к разыменованию нулевой ссылки\.

Рассмотрим пример:

```cpp
string Foo(WeakReference weak)
{
    return weak.Target.ToString();
}
```

Так как объект, на который 'WeakReference' хранит ссылку, может быть в любой момент очищен сборщиком мусора, всегда существует вероятность, что свойство 'Target' вернёт значение 'null'\.

В таком случае, при попытке вызова метода 'ToString' может произойти разыменование нулевой ссылки и будет выброшено исключение 'NullReferenceException'\. Один из вариантов защиты от потенциального удаления объекта – запись его в локальную переменную, на время работы с ним\. Исправленный код будет выглядеть так:

```cpp
string Foo(WeakReference weak)
{
    var weakTarget = weak.Target;
    return weakTarget != null ? weakTarget.ToString() : String.Empty;
}
```

После записи ссылки в локальную переменную, сборщик мусора уже не сможет удалить этот объект, пока ссылка на него находится на стеке\. Тем не менее, после записи объекта в локальную переменную её обязательно нужно проверить на 'null', т\.к\. в момент доступа к свойству 'Target' объект, на который 'Target' указывал, уже мог быть удалён сборщиком мусора\.

Проверка на существование объекта внутри 'WeakReference' с помощью свойства 'IsAlive' также не защитит от возникновения 'NullReferenceException', так как между проверкой 'IsAlive' и разыменованием свойства 'Target' объект также может быть удалён сборщиком мусора:

```cpp
char Foo(WeakReference weak)
{
  if (weak.IsAlive)
     return (weak.Target as String)[0];
  return ' ';
}
```

Корректное использование свойства 'IsAlive' может выглядеть так:

```cpp
char Foo(WeakReference weak)
{
  var str = weak.Target as String;
  if (weak.IsAlive)
     return str[0];

  return ' ';
}
```