Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different property values on two references to the same object (C#)

I am trying to track down a very elusive bug in an application that manipulates a FlowDocument. I have shown below three consecutive lines of debugging code, together with their output:

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

Can anyone help me to understand how two references to the same object can have different values for a given property? Or am I missing something about the way ReferenceEquals works?

Thanks,

Tim

Edit:

If I change the assertion to an if block, the debugging code never runs ...

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

... which makes me feel utterly stupid, because the ReferenceEquals test is clearly working, but I don't understand why the assertion is not working.

like image 414
Tim Coulter Avatar asked Feb 27 '23 14:02

Tim Coulter


2 Answers

Two things that might be happening from the top of my mind:

  • Accessing Blocks or Blocks.Count might mutate state (it shouldn't, but it is possible).
  • The object might be changed on another thread between the two calls. Do you use multi-threading in the application ?

Also, if the references are of different types (ie. document2 is of an inherited type), the property might be overloaded to return something different. You could check to see whether document1.GetType() == document2.GetType().

Edit in response to your update

Debug.Assert will only ever run, if the assembly is compiled in Debug mode. If you are running Release, it will not be run. This is because Debug.Assert is decorated with the [Conditional("DEBUG")] attribute.

It seems that the issue is the fact that you indeed have 2 different objects.

like image 158
driis Avatar answered Apr 30 '23 11:04

driis


If a property has side effects it can yield different results each time you call it. E.g. DateTime.Now does not always equal DateTime.Now.

Without knowing anything more about the code, that would be my guess.

EDIT: Using Reflector on FlowDocument shows that Blocks return a new instance each time it is called. Additionally, the Count property BlockCollection is rather elaborate, so I would take a closer look at that. Unfortunately I don't know the involved types very well, so I can't immediately tell you what is wrong.

like image 23
Brian Rasmussen Avatar answered Apr 30 '23 13:04

Brian Rasmussen