Свойства по сути маскируют в себе обычные методы для извлечения/установки полей.
Представим что есть такой метод:
public string GetValue()
{
return GetValue();
}
Здесь содержится только новый рекурсивный вызов. Какой результат будет получен при вызове такого метода? Естественно, StackOverflowException.
Поэтому каждому свойству должно соответствовать какое-то поле.
private string _actNumber;
public string ActNumber {
get { return _actNumber; }
set { _actNumber = value; }
}
Во многих случаях не требуется какая-то определенная проверочная логика, поэтому в языке предусмотрены специальные конструкции (как, например, авто-свойства)
public string ActNumber { get; set; }
Что, конечно, может сбить с толку когда потребуется дополнительные условия.
----
По поводу второй части вопроса. Обрабатывать null - результат нужно на самом верхнем (допустимом) уровне.
В C# для этого есть целый набор null-операторов:
?., ??, ??=
о которых можно прочитать, например, в справке:
?? and ??= operatorsNull-conditional operators ?. and ?[]