Почему перегрузка постфиксного и префиксного оператора++ в C# это один метод, а в С++ - два?

145
17 апреля 2022, 11:30

Не понимаю, как работает перегрузка в C#, с плюсами всё ясно. Как метод выполняет и префиксную, и постфиксную функцию? Опишите максимально подробно, пожалуйста.

код на C#:

    public static Car operator ++(Car car) // ++ один префикс и постфикс!
    {
        return new Car{ benzine = car.benzine + 1};
    }

код на C++:

Car& Car::operator++()
{
   this->benzine++;
   return *this;
}
Car Car::operator++(int unused)
{
   Car car = *this;
   ++this->benzine;
   return car;
}
Answer 1

В C# имеется только оператор Increment. Если он пишется до значения, то в качестве результата компилятор использует новое значение, если после - то старое. При этом входящей переменной в обоих случаях присваивается новое значение. А входящий объект не изменяется, причем в случае префиксного оператора ссылка на него просто теряется.

using System;
using System.Diagnostics;
namespace ConsoleApp1
{
    class Dummy
    {
        private String m_tag;
        public Dummy(String tag)
        {
            m_tag = tag;
        }
        public override String ToString()
        {
            return m_tag;
        }
        public static Dummy operator ++(Dummy initial)
        {
            return new Dummy("mutated");
        }
    }
    class Program
    {
        static void Main(String[] args)
        {
            var original = new Dummy("original");
            {
                var input = original;
                var output = ++input;
                Debug.Assert("original" == original.ToString());
                Debug.Assert("mutated" == input.ToString());
                Debug.Assert("mutated" == output.ToString());
                Debug.Assert(!Object.ReferenceEquals(input, original));
                Debug.Assert(!Object.ReferenceEquals(output, original));
                Debug.Assert(Object.ReferenceEquals(input, output));
            }
            {
                var input = original;
                var output = input++;
                Debug.Assert("original" == original.ToString());
                Debug.Assert("mutated" == input.ToString());
                Debug.Assert("original" == output.ToString());
                Debug.Assert(!Object.ReferenceEquals(input, original));
                Debug.Assert(Object.ReferenceEquals(output, original));
                Debug.Assert(!Object.ReferenceEquals(input, output));
            }
        }
    }
}

В С++ это два совершенно раздельных оператора. Причем обычно подразумевается модификация объекта на месте, а ребиндинг ссылок вообще не допускается.

READ ALSO
Убрать пробел после запятой в строке JS

Убрать пробел после запятой в строке JS

У меня есть строка , допустим "1 777,97 2"Мне нужно убрать пробелы после запятой, но чтобы пробелы перед запятой - остались

177
btoa base64 из объекта File js

btoa base64 из объекта File js

Я загружаю файл в формате через input file и могу получить к нему доступ через eventtarget

123
Как нацепить эвент на объект класса

Как нацепить эвент на объект класса

Как нацепить евент на объект класса?

128