Постинкремент x на n (n!= 1)
Итак, если я выполню следующий код...
int x = 0;
Debug.WriteLine(x++);
Debug.WriteLine(x += 4);
Debug.WriteLine(x);
... получаю 0, 5 и 5 соответственно. Однако я бы хотел получить 0, 1 и 5. Есть ли способ сделать постинкремент на n в C#? Или я должен написать += как собственное утверждение?
Просто для контекста то, что я на самом деле делаю, это набор операций BitConverter над буфером, и было бы очень хорошо иметь каждую из них в качестве самодостаточного оператора, где смещение увеличивается на размер типа данных, являющихся конвертировано в. Таким образом, если формат буфера будет позже изменен, я могу просто добавить или удалить одну строку, не беспокоясь ни о каком окружающем коде.
3 ответа
Вы должны иметь возможность злоупотреблять Interlocked.Exchange, чтобы получить старое значение переменной и в то же время заменить ее значение:
Debug.WriteLine(Interlocked.Exchange(ref x, x+4));
другими словами, замените значение переменной x
с x + 4
но вернуть предыдущее значение x
,
Редактировать:
Разборка показывает, что это "увеличение на 4 и перестановка" выполняется в 4 инструкциях - никакого вызова вообще не требуется, поэтому производительность должна быть хорошей:
Interlocked.Exchange(ref x, x + 4);
0000005e mov eax,dword ptr [rbp+2Ch]
00000061 add eax,4
00000064 xchg eax,dword ptr [rbp+2Ch]
00000067 mov dword ptr [rbp+28h],eax
Неинтуитивный характер этого (и других) решений, вероятно, сводится к нарушению принципа CQS - мы изменяем переменную и возвращаем значение сразу, т.е. не то, что мы должны делать в основном потоке.
Насколько я знаю, это невозможно. Вы можете написать свой метод-обертку так:
static void ExecuteWithPost(ref int value, Action<int> operation, Func<int, int> postOperation)
{
operation(value);
value = postOperation(value);
}
и использовать это:
int i = 0;
ExecuteWithPost(ref i, x => Debug.WriteLine(x), x => x + 1);
ExecuteWithPost(ref i, x => Debug.WriteLine(x), x => x + 4);
ExecuteWithPost(ref i, x => Debug.WriteLine(x), x => x);
Печатает, что вы хотите.
Метод обертки может быть универсальным, чтобы заставить его работать с другими типами, кроме int
:
static void ExecuteWithPost<T>(ref T value, Action<T> operation, Func<T, T> postOperation)
{
operation(value);
value = postOperation(value);
}
Оператор ++
это короткая форма x = x + 1;
так используя +=
неплохая идея
Если я вас правильно понимаю
int x = 0;
Debug.WriteLine(x++); //return 0
Debug.WriteLine(x); //return 1
Debug.WriteLine(x += 4); //return 5
Я бы предложил вам использовать оператор +=
потому что любой другой способ перегрузки оператора или что-то еще; будет просто накладные расходы.