Реальный ответ, даже если его действительно трудно понять, если вы его не использовали, заключается в том, что вы теряете выразительность. В языке есть понятия, которые вы не можете выразить в C #, и они имеют значение, они являются частью дизайна, но потеряны при переводе в код.
Это не ответ, а пример:
Учтите, что у вас есть контейнер, отсортированный по полю хранимых элементов. Эти объекты действительно большие. Вам необходимо предложить доступ к данным для читателей (рассмотрите возможность отображения информации в пользовательском интерфейсе).
Теперь в C # / Java вы можете пойти одним из двух способов: либо сделать копию для использования вызывающей стороной (гарантирует, что данные не изменятся, но неэффективны), либо вы вернете ссылку на внутренне удерживаемый файл. объект (просто надеясь, что вызывающая сторона не изменит ваши данные через сеттеры).
Если пользователь получает ссылку и изменяет через нее поле, которое служит индексом, то ваши инварианты контейнера нарушаются.
В C ++ вы можете вернуть константу-ссылку / указатель, и компилятор отключит вызов методов установки (мутирующих методов) в возвращаемом вами экземпляре. Вы получаете и безопасность, которую пользователь не изменит (*), и эффективность в вызове.
Третий, не упомянутый ранее, параметр делает объект неизменным, но это повсеместно запрещает изменения. Совершенно контролируемые изменения объекта будут запрещены, и единственная возможность изменения - создание нового элемента с выполненными изменениями. Это составляет время и пространство.