Тонкости поведения свойств C# при отладке кода в Visual Studio

В данной статье речь пойдёт о таком языковом средстве C#, как свойства. Думаю, все знают, что это такое и лишний раз не нужно упоминать об этом. Но вот есть один нюанс, связанный с ними во время отладки. Когда начинающие разработчики, и не только, натыкаюся на него, то думают, что это баг. Чтобы продемонстрировать данную особенность рассмотрим код приведённый ниже:
using System.Collections.Generic;
 
namespace Test
{
  class Program
  {
    static void Main(string[] args)
    {
      Test test = new Test();
      test.List = new List<int>();
      test.List = null;
      List<int> temp = test.List;
    }
  }
  public class Test
  {
    public Test() { }
    private List<int> list = null;
    public List<int> List
    {
      get
      {
        if (list == null)
          list = new List<int>();
        return list;
      }
      set
      {
        list = value;
      }
    }
  }
}
На первый взгляд ничего особенного в нём нет. Попробуем пройтись по нему отладчиком. Ставим точки останова в нужные места и запускаем. Сначала создаётся объект нашего класса. Потом явно ему присваиваем новую ссылку на целочисленный список. Удаляем эту ссылку присвоив test.List значение null. Видим что
 


что внутреннему полю действительно присвоилось значение null. Дальше видно, что
 


свойство которому присвоено было null не является пустым. А новая ссылка temp будет содержать значение вмето ожидаемого null. Как такое может быть? Всё просто, если вспомнить, что свойсва - просто методы. Но дело этим не ограничивается. Тут вмешивается отладчик Visual Studio, который и вводит разработчиков в замешательство, заставляе думать, что код работает неверно. Когда мы наводим указатель мыши, то отладчик просто вызывает метод, чтобы получит его значение. И тут срабатывает наш код аксессора get:
get
{
  if (list == null)
    list = new List<int>();
  return list;
}
Но мы то думали, что проходим по коду по шагам и вроде нигде ничего не инициализировали. На самом деле это так и есть. В этом можно убедиться, отключив одну опцию в настройках отладки (Включить вычисление свойств и другие неявные вызовы функций).
 


Тогда всё встанет на свои места.
 


Как видно, всё так как и ожидалось. Просто теперь не будет контекстного меню, при наведении указателя на свойство в редакторе. Просто запомните это, в следующий раз, когда будете писать код или столкнётесь с подобным.