Вопрос: Зачем/Для чего нужен данный код?

Лучший ответ:
Это геттеры и сеттеры. То есть функции доступа к свойству.
Зачем? Попробую объяснить простым языком. Большие программы сложно полностью загрузить в мозг отдельного человека и представлять всю структуру целиком со всеми нюансами одновременно. Поэтому принято делить программу на части. Вынос кода в отдельную функцию - один из простых способов. В ООП к этой проблеме подходят более основательно. Класс как явление - тому пример.
Класс делит программу как минимум на 2 части - то, что внутри класса, и то, что снаружи класса. Считается как бы, что класс пишет один человек, а пользуется им другой человек. Но это может быть и один единственный человек, всё равно так проще, потому что человек сначала пишет класс, тщательно всё там кодит и тестирует, а потом напрочь ЗАБЫВАЕТ, как он устроен внутри, потому что он уже готов и им можно пользоваться. То есть человек выгружает из своей ненадежной человеческой памяти эту инфу и переходит к следующей задаче, в которой просто использует этот класс. Всё, что ему нужно помнить, это то, как пользоваться классом, а всю подноготную можно забыть до тех пор, пока не понадобится улучшить класс. И здесь снова получается удобно. Когда будем улучшать класс (это не обязательно тот же самый человек), можно не думать о том, как его используют. Главное, чтобы способ взаимодействия с классом не изменился (не сильно изменился).
В вашем примере - это просто заготовка. Дальше нужно наполнять эту заготовку функционалом. В самом простом виде геттер просто возвращает приватное свойство, а сеттер меняет его. Так нужно сделать сразу, чтобы потом не пришлось переписывать всю программу (и согласовывать с коллегами). Но даже здесь уже есть небольшое правило - нельзя передавать отрицательные значения. Условия могут быть сложнее. И вообще всё может быть сложнее. Например, вместо age можно хранить дату рождения. И функция GetAge будет каждый раз высчитывать разницу с текущей датой. По сути для внешнего использования ничего не меняется, но внутри происходит магия.

Худший ответ:
Сейчас постараюсь объяснить своими словами, а ниже прикреплю более полную и точную информацию.
0. age - приватная переменная, которая доступна только в пределах этого класса.
1. GetAge() - публичная (открытая для всех классов) функция, которая возвращает значение приватной (скрытой от других классов) переменной. Часто называют геттер, от слова Get.
2. SetAge() - публичная функция, которая устанавливает значение приватной переменной. Называется сеттер, от слова Set.Для чего это нужно?
В первую очередь, для безопасности, а также:
- соблюдение одного из основных принципов ООП (на котором и построен C#) - инкапсуляция.
- для того, чтобы нельзя было напрямую изменять переменную из других классов.
- для того, чтобы задавать дополнительные условия.
Например, в SetAge() можно написать условие, при котором возраст можно указать только в пределах от 0 до 100, это позволит избежать множества ошибок.
Также в C# существует более удобный синтаксис:public int Age { get; set; }
Это если нужно просто принимать или устанавливать значение, также set или get можно вообще не писать, если он не нужен. А для более сложной логики можно написать так:private int _age;
public int Age
{
    get
    {
        return _age;
    {
    set
    {
        if(value > 0) _age = value;
    }
}
Статья на docs.microsoft:
https://docs.microsoft.com/ru-ru/dotnet/csharp/pro...
Статья про инкапсуляцию и для чего нужны get/set:
https://metanit.com/sharp/tutorial/3.4.php