# V3189. The assignment to a member of the readonly field will have no effect when the field is of a value type. Consider restricting the type parameter to reference types.

Анализатор обнаружил, что члену 'readonly' поля присваивается значение, и при этом поле может иметь значимый тип. Если поле будет иметь значимый тип, то изменения члена поля не произойдёт.

Подобная ошибка возникает из-за того, что типы значений непосредственно содержат свои данные. Если тип поля явно определён как значимый, то подобную ошибку найдёт компилятор. Однако если типом поля является универсальный параметр, то код успешно скомпилируется. Из-за этого возможна ситуация, когда в член 'readonly' поля происходит запись, но его значение не изменяется.

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

    private interface ITable
    {
      int Rows { get; set; }
    }

    private class Table<T> where T : ITable
    {
      private readonly T _baseTable;

      public void SetRows(int x)
      {
        _baseTable.Rows = x;     // <=
      }
    }

Класс имеет поле '_baseTable', типом которого является универсальный параметр. В методе 'SetRows' свойству 'Rows' данного поля присваивается значение аргумента.

Ниже представлен пример использования этого класса:

    private struct RelationTable : ITable
    {
      public int Rows { get; set; }
    }
    ....
    static void DoSomething()
    {
      Table<RelationTable> table = new Table<RelationTable>();
      table.SetRows(10);
    }

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

    private interface ITable
    {
      int Rows { get; set; }
    }

    private class Table<T> where T : class, ITable
    {
      private readonly T _baseTable;

      public void SetRows(int x)
      {
        _baseTable.Rows = x;
      }
    }