Различные значения свойств для двух ссылок на один и тот же объект (C #) - PullRequest
4 голосов
/ 24 июля 2010

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

Debug.Assert(ReferenceEquals(document1, document2));
Debug.WriteLine(document1.Blocks.Count); // 1
Debug.WriteLine(document2.Blocks.Count); // 3

Может кто-нибудь помочь мне понять, как две ссылки на один и тот же объект могут иметь разные значения для данного свойства?Или я что-то упускаю из-за того, как ReferenceEquals работает?

Спасибо,

Тим

Редактировать:

Если я изменю утверждение на if блок, код отладки никогда не запускается ...

if (ReferenceEquals(document1, document2))
{
    Debug.WriteLine(document1.Blocks.Count);
    Debug.WriteLine(document2.Blocks.Count);
}

... что заставляет меня чувствовать себя совершенно глупо, потому что тест ReferenceEquals явно работает, но я не понимаю, почему утверждениене работает.

Ответы [ 4 ]

4 голосов
/ 24 июля 2010

Две вещи, которые могут происходить из моей головы:

  • Доступ к блокам или блокам. Количество может изменить состояние (не должно, но это возможно).
  • Объект может быть изменен в другом потоке между двумя вызовами. Используете ли вы многопоточность в приложении?

Кроме того, если ссылки имеют разные типы (т. Е. Document2 имеет унаследованный тип), свойство может быть перегружено для возврата чего-то другого. Вы можете проверить, есть ли document1.GetType() == document2.GetType().

Редактировать в ответ на ваше обновление

Debug.Assert будет запускаться только в том случае, если сборка скомпилирована в режиме отладки. Если вы используете Release, он не будет запущен. Это связано с тем, что Debug.Assert имеет атрибут [Conditional("DEBUG")].

Кажется, проблема в том, что у вас действительно есть 2 разных объекта.

2 голосов
/ 24 июля 2010

Если свойство имеет побочные эффекты, оно может давать разные результаты при каждом вызове. Например. DateTime.Now не всегда равно DateTime.Now.

Не зная ничего больше о коде, это было бы моим предположением.

РЕДАКТИРОВАТЬ: Использование Reflector на FlowDocument показывает, что блоки возвращают новый экземпляр каждый раз, когда он вызывается. Кроме того, свойство CountCollection довольно сложное, поэтому я бы более внимательно на это посмотрел. К сожалению, я не очень хорошо знаю задействованные типы, поэтому не могу сразу сказать вам, что не так.

1 голос
/ 24 июля 2010

Возможности (некоторые из которых вы уже обесценили в комментариях):

  1. Какой-то внешний процесс, например, загрузка блоков в FlowDocument, изменяет значение между записями.

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

  3. Если бы экземпляры были объявлены как разные типы, их ссылки все равно были бы равны, нозначение Blocks (или Blocks.Count) может быть переопределено, что приведет к различным возвращаемым значениям, так как может быть вызван другой код - как Object.ToString () против Int.ToString ().

  4. Вы как-то вызываете этот код отладки в середине цикла.Это может произойти, если вы запускаете его в командном окне или в каком-либо прикрепленном отладчике, а не в приложении.

  5. У вас есть битые пиксели на экране, которые создают первый «3» видкак «1».

  6. Вы живете рядом с ядерным реактором.

Некоторые вещи, которые нужно попробовать:

  1. Запустите ваш код .Assert в цикле и посмотрите, стабилизируются ли значения.

  2. Установите точку останова чтения / записи в значении Blocks.(Я знаю, что вы можете сделать это в C, но еще не пробовал в C #)

Обновление

По поводу вашего дополнительного вопроса о.Assert () не работает должным образом:

Только что посмотрел эту заметку на MSDN относительно Debug.Assert () .

По умолчанию Debug.Assertметод работает только в отладочных сборках.Используйте метод Trace.Assert, если вы хотите делать утверждения в сборках выпуска.Для получения дополнительной информации см. Утверждения в управляемом коде.

Выполняется ли отладочная сборка или сборка выпуска?

1 голос
/ 24 июля 2010

Вы уверены, что ссылка на объект Blocks указывает на один и тот же объект?Попробуйте

Debug.Assert(ReferenceEquals(document1.Blocks, document2.Blocks));

и посмотрите, удастся ли это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...