Всегда ли свойства имеют значение, когда не установлены? - PullRequest
7 голосов
/ 27 января 2012

У меня есть такое свойство:

public Tuple<String, String>[] Breadcrumbs { get; set; }

и у меня есть тест в одном из моих методов, таких как:

if (Breadcrumbs != null && Breadcrumbs.Length > 0) { }

В зависимости от того, когда вызывается этот метод, Breadcrumbs может не быть установлен. В одном тесте Breadcrumbs == null оценивается как истина.

У неустановленных свойств всегда будет значение? (Это всегда будет null?)

Ответы [ 4 ]

19 голосов
/ 27 января 2012

Автоматически реализуемое свойство, которое не было явно задано каким-либо кодом, всегда будет иметь значение по умолчанию для типа свойства, которое равно нулю для ссылочных типов. (Для int это будет 0, для char это будет '\ 0' и т. Д.).

Автоматически реализованное свойство, подобное этому, просто эквивалентно:

private PropertyType property;
public PropertyType Property
{
    get { return property; }
    set { property = value; }
}

... за исключением того, что вспомогательная переменная имеет невыразимое имя (вы не можете ссылаться на него в коде), поэтому она всегда будет начинаться со значения по умолчанию для типа.

3 голосов
/ 27 января 2012

Авто-свойства используют вспомогательные поля и компилируются в обычные свойства.

Если свойство-тип является ссылочным типом, значение будет нулевым, если не будет значением по умолчанию.

2 голосов
/ 27 января 2012

Переменные-члены класса (называемые полями) и, следовательно, вспомогательные переменные свойств, всегда инициализируются значением по умолчанию, если они не инициализированы явно, то есть null для ссылочных типов. Значением по умолчанию для всех типов является значение, двоичное представление которого состоит из всех битов, установленных на 0.

С другой стороны, C # требует явной инициализации локальных переменных. Это: переменные, объявленные в методах, конструкторах и средствах доступа к свойствам и out параметры метода; то есть они обрабатываются как неопределенные, пока вы не назначите им значение.

0 голосов
/ 27 января 2012

Логически невозможно, чтобы оно не имело значения. Он должен будет вернуть что-то, некоторую группу из 1 и 0, которая, по крайней мере, считается ссылкой на Tuple<String, String>[], поэтому в этом смысле она имеет значение.

Это также тот случай, когда все поля в классах устанавливаются в их значения по умолчанию (default(T) для любого типа T они есть, null для всех ссылочных типов). В противном случае было бы возможно иметь объект, который находился бы в состоянии, которое не только не имело бы никакого смысла с точки зрения того, что он делает, но и не имело никакого смысла по правилам того, что .NET ожидает от объектов. Это включает в себя скрытые поля за автоматическими свойствами.

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

public Tuple<String, String>[] Breadcrumbs
{
  get
  {
    Tuple<String, String>[] whatIWillSend;
    return whatIWillSend;
  }
}

Если бы это было разрешено, whatIWillSend имел бы значение, определяемое не каким-либо осознанным решением с вашей стороны, а тем, что случилось в памяти в то время. Это может быть ноль, это может быть действительный Tuple<String, String>[] по простому совпадению (но не тот, который вы хотели использовать!), Это может быть Dictionary<int, List<string>>, что среда выполнения теперь подумает на самом деле Tuple<String, String>[] ( там идет безопасность типов всей системы), это может быть четверть структуры decimal. (В языках, допускающих такие вещи, также может быть общеизвестным значением, которое отладчики для таких языков устанавливают в этих случаях именно так, чтобы помочь находить ошибки, вызванные этим).

Это самая близкая вещь, которую мы можем получить к свойству, не имеющему значения. Обратите внимание, что:

  1. Это все равно будет иметь значение, но не значащее значение.
  2. Нам все равно не разрешено делать это в C #.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...