Объясните пожалуйста как работает этот код на c#

Я не могу разобраться как здесь работают делегаты, события и их обработчики, а также что происходит в строках типа "Notify?.Invoke(this, new AccountEventArgs("Недостаточно денег на счете", sum));". Да я и впринцепе мало что тут понимаю (код с метанита, но тамошнее объяснение очень скудное).

Это что то вроде реализации банковской системы, где есть счет пользователя и возможность взаимодействовать с ним, но с использованием делегатов и событий.

Вот сам код:

```
namespace Name
{
    class Program {
static void Main(string[] args) {
        Account acc = new Account(100);
        acc.Notify += DisplayMessage;
        acc.Put(20);
        acc.Take(70);
        acc.Take(150);

        void DisplayMessage(Account sender, AccountEventArgs e)
        {
            Console.WriteLine($"Сумма транзакции: {e.Sum}");
            Console.WriteLine(e.Message);
            Console.WriteLine($"Текущая сумма на счете: {sender.Sum}");
        }
    }

    public class AccountEventArgs
    {
        // Сообщение
        public string Message { get; }
        // Сумма, на которую изменился счет
        public int Sum { get; }
        public AccountEventArgs(string message, int sum)
        {
            Message = message;
            Sum = sum;
        }
    }

    public class Account
    {
        public delegate void AccountHandler(Account sender, AccountEventArgs e);
        // принимает объект, который вызвал событие, то есть текущий объект Account.
        // принимает объект AccountEventArgs, который хранит информацию о событии, получаемую через конструктор.
        public event AccountHandler? Notify;

        public int Sum { get; private set; }

        public Account(int sum) => Sum = sum;

        public void Put(int sum)
        {
            Sum += sum;
            Notify?.Invoke(this, new AccountEventArgs($"На счет поступило {sum}", sum));
        }
        public void Take(int sum)
        {
            if (Sum >= sum)
            {
                Sum -= sum;
                Notify?.Invoke(this, new AccountEventArgs($"Сумма {sum} снята со счета", sum));
            }
            else
            {
                Notify?.Invoke(this, new AccountEventArgs("Недостаточно денег на счете", sum));
            }
        }
    }
}
}
``` 

Ответы (0 шт):