﻿# V3111\. Checking value for null will always return false when generic type is instantiated with a value type\.

Анализатор обнаружил, что значение, имеющее обобщённый \(generic\) тип, сравнивается с 'null'\. Если обобщённый тип никак не ограничен, то он может быть инстанциирован как значимым, так и ссылочным типом\. В случае если он окажется значимым, проверка на 'null' всегда будет возвращать 'false', так как значимые типы не могут принимать нулевое \(null\) значение\. 

Рассмотрим пример\.

```cpp
class Node<T>
{
  T value;
  void LazyInit(T newValue)
  {
    if (value == null) // <=
    {
      value = newValue;
    }
  }
}
```

В случае если тип 'T' будет определен как значимый, тело условия 'if' никогда не выполнится\. В нашем примере это приведёт к тому, что переменная 'value' не будет проинициализирована переданным значением \- её значение всегда останется равным 'default' значению 'T'\.

Если необходимо обрабатывать объекты только ссылочного типа, то используйте ограничители\. К примеру, generic тип 'T' из примера выше может быть ограничен только для ссылочных типов:

```cpp
class Node<T> where T : class // <=
{
  T value;
  void LazyInit(T newValue)
  {
    if (value == null) 
    {
      value = newValue;
    }
  }
}
```

Если же generic тип должен принимать как значимые, так и ссылочные типы, и проверка должна осуществляться для обоих видов значений, то тогда необходимо использовать проверку на значение данного типа по умолчанию \(default\), вместо проверки на 'null':

```cpp
class Node<T>
{
  T value;
  void LazyInit(T newValue)
  {
    if (object.Equals(value, default(T))) // <=   
    {
      value = newValue;
    }
  }
}
```

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

```cpp
class Node<T>
{
  T value;
  void LazyInit(T newValue)
  {
    if (typeof(T).IsClass && // <=   
        object.Equals(value, default(T))) 
    {
      value = newValue;
    }
  }
}
```

Метод 'IsClass' вернет 'true' если generic был инстанциирован ссылочным типом\. Таким образом, проверка на значение по умолчанию будет происходить только для ссылочных типов, по аналогии с предыдущим примером\.