Правда в том, что не так много было бы потеряно, если бы поля были вынуждены быть закрытыми в языке. Как вы говорите, в большинстве языков рекомендуется инкапсулировать все поля с помощью метода установки / получения свойств. Язык вполне может заставить все поля быть закрытыми.
Однако, если у вас есть что-то вроде закрытого внутреннего класса:
public class OuterClass
{
private InnerClass
{
public int publicField;
}
}
Тогда вы можете утверждать, что геттеры / сеттеры не требуются. В этом случае в C # так же просто использовать автоматически реализуемое свойство. Однако они были введены только в C # 2, поэтому я думаю, что это причина того, что открытые поля все еще разрешены. Предварительно автоматически реализованные свойства, можно было бы написать геттеры / сеттеры, что можно считать излишним для частного внутреннего класса.
В языках с указателями, таких как C ++, публичные поля обязательны, если кто-то хочет получить указатель на поле извне класса.