проверка должна быть упрощена до:
поздно вечером на работе мы пытались понять, почему что-то не получается. Проверка проверки не удалась, когда это не должно было произойти.
Мы закончили тем, что добавили оператор 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 как ошибка, которая будет исправлена в следующем выпуске.