Результат посфиксного икремента - значение аргумента до прибавления 1
То есть код j = j++ можно представить так
int tmp = j;
j = j + 1;
j = temp;
Если посмотреть IL то в j = j++ будет такой код
IL_0006: ldloc.0 // В стек кладем значение j (оно у нас == 0)
IL_0007: dup // Дублируем в стеке значение j
IL_0008: ldc.i4.1 // Кладем второй аргумент инкремента (он == 1)
IL_0009: add // Складываем два верних значения, результат кладем в стек
IL_000a: stloc.0 // Сохраняем в j результат сложения
IL_000b: stloc.0 // Сохраняем в j 0, который получился при dup
Я нарисовал, что получается в стеке. Тут интересен опкод dup, который как раз делает int tmp = j;