проверка должна быть упрощена до:

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

Мы закончили тем, что добавили оператор print к этому коду (дизассемблированный из Reflector для проверки того, что код на самом деле был тем, что мы написали):

public static string Redacted(string name, DateTime lastModified)
{
    long ticks = lastModified.Ticks;
    if ((ticks != (ticks - (ticks % 10000L))) &&
            (lastModified != DateTime.MaxValue))
    {
        Log.Debug(string.Format("Last Modified Date = '{0}'. Ticks = '{1}'. TicksCalc = '{2}'",
            lastModified.ToString("dd/MM/yyyy hh:mm:ss.fff"),
            ticks, ticks - (ticks % 10000L)));

Было напечатано (переформатировано):

Last Modified Date = '22/03/2011 12:16:22.000'.
Ticks     = '634363497820000000'.
TicksCalc = '634363497820000000'            

Но условие таково, чтоticks«(что равно тикам, напечатанным выше) не равно»(ticks - (ticks % 10000))"(что равно TicksCalc)! 634363497820000000! = 634363497820000000 ?!

Чтобы определить, что здесь происходит, мы добавили еще два утверждения:

long ticks = lastModified.Ticks;
/* Added following two lines: */
long num2 = ticks - (ticks % 10000L);
Log.Debug((ticks == num2).ToString());
/* */
if ((ticks != (ticks - (ticks % 10000L))) &&
        (lastModified != DateTime.MaxValue))
{
    Log.Debug(string.Format("Last Modified Date = '{0}'. Ticks = '{1}'. TicksCalc = '{2}'",
        lastModified.ToString("dd/MM/yyyy hh:mm:ss.fff"),
        ticks, ticks - (ticks % 10000L)));

Как и должно быть, этот напечатанtrue (при тестировании с одинаковым значением) и не написал вторую строку.

Чувствуя себя немного потерянным, мы снова удалили две строки, перекомпилировали и перезапустили. Исходное поведение повторилось.

Этим утром,Я записал видео.

Видео в первую очередь показывает достижение точки останова в методе с использованием «сломанного» кода, а затем повторное построение и повторный запуск с использованием «рабочего» кода. Обратите внимание, что хотя отладчик показывает, чтоif состояние оценивается какfalse, тело все еще введено.

Я видел подобные вещи раньше, когда наблюдал отладчик, потому что отладчик заставлял некоторые вещи оцениваться, но это происходит независимо от того, используется ли отладчик.

Кроме того, это происходит только в режиме Release (т.е. с включенной оптимизацией JIT).

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

Я надеюсь, что ответ не является чем-то очевидным, что я полностью упустил из виду ...!

Редактировать: вот ил. Я не думаю, что с этим что-то не так, потому что он декомпилируется в правильный C #:

Не работаетРаботает

Обновить:

Подтверждено Microsoft как ошибка, которая будет исправлена ​​в следующем выпуске.

Ответы на вопрос(5)

Ваш ответ на вопрос