Анализатор обнаружил небезопасное использование объекта типа 'WeakReference', которое может привести к разыменованию нулевой ссылки.
Рассмотрим пример:
string Foo(WeakReference weak) { return weak.Target.ToString(); }
Так как объект, на который 'WeakReference' хранит ссылку, может быть в любой момент очищен сборщиком мусора, всегда существует вероятность, что свойство 'Target' вернёт значение 'null'.
В таком случае, при попытке вызова метода 'ToString' может произойти разыменование нулевой ссылки и будет выброшено исключение 'NullReferenceException'. Один из вариантов защиты от потенциального удаления объекта – запись его в локальную переменную, на время работы с ним. Исправленный код будет выглядеть так:
string Foo(WeakReference weak) { var weakTarget = weak.Target; return weakTarget != null ? weakTarget.ToString() : String.Empty; }
После записи ссылки в локальную переменную, сборщик мусора уже не сможет удалить этот объект, пока ссылка на него находится на стеке. Тем не менее, после записи объекта в локальную переменную её обязательно нужно проверить на 'null', т.к. в момент доступа к свойству 'Target' объект, на который 'Target' указывал, уже мог быть удалён сборщиком мусора.
Проверка на существование объекта внутри 'WeakReference' с помощью свойства 'IsAlive' также не защитит от возникновения 'NullReferenceException', так как между проверкой 'IsAlive' и разыменованием свойства 'Target' объект также может быть удалён сборщиком мусора:
char Foo(WeakReference weak) { if (weak.IsAlive) return (weak.Target as String)[0]; return ' '; }
Корректное использование свойства 'IsAlive' может выглядеть так:
char Foo(WeakReference weak) { var str = weak.Target as String; if (weak.IsAlive) return str[0]; return ' '; }
Данная диагностика классифицируется как:
Взгляните на примеры ошибок, обнаруженных с помощью диагностики V3145. |