Смотрите ситуация следующая: если Вы работаете с полем напрямую (оно открытое/ public), тогда Вы будете присваивать любые значения данному полю, а у Вас некоторые значения недопустимы для записи.
Рассмотрим достаточно простой пример:
у нас есть класс Devider и у него есть два поля (a и b) и метод Div, у которого нету параметров и он возвращает результат деления a на b. С этого следует, что b не должно принимать значение 0.
Если Вы будете работать напрямую с полем, тогда Вы не сможете запретить запись 0 в переменную b, что приведёт к необходимости установки дополнительных проверок во всех местах где Вы её будете использовать. Поэтому использование полей напрямую небезопасно.
Если же Вы будете работать со свойствами, то Вы можете ограничить запись определённых значений в поле через тело метода доступа get. И Вам ненужно будет устанавливать все проверки вручную (ведь они будут происходить автоматически при попытке присвоения значения полю). Поэтому Вы сможете с помощью свойств обезопасить себя от определённого рода ошибок (что зависит от логики в ваших методах доступа). К тому же свойства могут быть как только для чтения или записи, а открытое поле всегда будет открытым как для чтения, так и для записи (что не всегда хорошо)
желательно всегда использовать свойства, даже в таких ситуациях, кто гарантирует, что в дальнейшем Вы не захотите добавить проверки в этих свойствах? Если Вы будете использовать поля. Тогда Вам нужно будет переписать все участки кода использующее данное поле.
Если не хотите расписывать полностью такие свойства, тогда используйте автосвойства, например: