Если без шибко умных слов, то приватными поля нужно делать, чтобы код отображал намерения разработчика и чтобы скрывать детали реализации (польза второго менее очевидна).
Вот пример из комментариев о том, как делать не стоит:
class Character {
public double health;
public void TakeDamage(double damage) {
if(damage <= 0) return;
this.health -= damage;
if(this.health <= 0) {
this.Die();
}
// ...
}
public void Die() {
this.DoSomethingSpecial();
// ...
}
// Этот метод в будущем будет удалён, оставлен пока как костыль
public void DoSomethingSpecial() {/*...*/}
}
Потом спустя хз сколько времени ты вернулся к коду.
Как ты будешь вспоминать, как правильно стоит наносить урон персонажам?
Через TakeDamage или в каких-то случаях можно напрямую изменить поле health?
Если в каких-то случаях нужно напрямую использовать поле health, то в каких?
Если ошибёшься - возникнут закономерные баги.
Про скрытие деталей реализации:
Допустим, что ты решил добавить в игру поддержку модов.
Как разработчик мода поймёт, какие методы на персонажах можно вызывать не беспокоясь о том, что мод сломается в следующей версии игры?
Например без использования модификатора internal - разработчик мода может подумать, что этот метод можно вызывать, а по факту - в следующей версии ты, как разработчик игры, планируешь его удалить или изменить сигнатуру, что поломает мод.
+ если у тебя многие вещи сделаны через поля, то тогда ты не сможешь использовать интерфейсы (ну или их использование будет затруднено)