2013-12-09 5 views
10

Итак, если я выполнить следующий код ...пост-инкремент х п (п! = 1)

int x = 0; 
Debug.WriteLine(x++); 
Debug.WriteLine(x += 4); 
Debug.WriteLine(x); 

... Я получаю 0, 5 и 5, соответственно. То, что я хотел бы получить, однако, это 0, 1 и 5. Есть ли способ сделать post-increment на n в C#? Или мне нужно написать + = в качестве собственного заявления?

Просто для контекста, что я на самом деле делаю, это куча операций BitConverter в буфере, и было бы очень приятно, чтобы каждый из них был самодостаточным, где смещение увеличивается на величину тип данных преобразуется в. Таким образом, если формат буфера будет позже изменен, я могу просто добавить или удалить одну строку, не беспокоясь о каком-либо из окружающего кода.

+0

Я бы сказал, что это невозможно. – MarcinJuraszek

+0

просто так ясно, вы хотите, чтобы пост-приращение более чем на один? – Alden

+0

, используя ваш пример, вы никогда не получите «нуль» и «один» из этих трех «WriteLine's». –

ответ

6

Вы должны быть в состоянии злоупотребить Interlocked.Exchange, чтобы получить старое значение переменной в то же время, заменяя его значение :

Debug.WriteLine(Interlocked.Exchange(ref x, x+4)); 

другими словами, замените значение переменной x с x + 4 но возвращает предыдущее значение x.

Edit:

Демонтажные показывает, что это "приращение на 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 principle - мы мутируем переменную и возвращаем значение сразу, то есть не то, что мы должны делать в основном потоке.

+0

Это тоже очень приятно. Не интуитивно, ИМХО: вам нужно закрутить немного мозга, чтобы понять, что цель линии. –

+1

И я только что узнал что-то новое. Я дам ему попробовать и посмотрю, как он работает по сравнению с использованием x + = 4 в качестве отдельной операции. В конце концов, я всегда могу написать это как оператор в конце строки и сказать StyleCop, что делать с собой, когда он жалуется на несколько операторов в одной строке. :) Это, в основном, сердце долговременной операции, так что все, что бы ни выиграло! – RobinHood70

+1

Просто протестировал его, и производительность была на одном уровне с написанием пользовательской функции, но не удивительно, медленнее, чем просто добавление дополнительных x + = 4. – RobinHood70

0

Оператор ++ короткая форма x = x + 1; поэтому использование += не плохая идея:

Если я вас правильно понял:

int x = 0; 
Debug.WriteLine(x++); //return 0 
Debug.WriteLine(x); //return 1 
Debug.WriteLine(x += 4); //return 5 

Я хотел бы предложить вам использовать оператор +=, потому что любой другой оператор пути перегрузка или что-то еще; будет просто накладными расходами.

+1

Это не «пост-инкремент на 4», как x ++, это приращение на 4. –

4

Насколько я знаю, это невозможно. Вы можете написать свой метод обертку так:

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); 
} 
+0

Передо мной: я бы написал что-то вроде этого. Мне не нравится «ref», и я бы предпочел вернуть обновленное значение. Просто на вкус. –

+0

Я думал о том, чтобы сделать что-то подобное, но решил, что это, вероятно, добавит слишком много накладных расходов. Мне нравится ваше решение, однако, гораздо более общий и элегантный, чем мой! – RobinHood70