Do you override .ToString() on all of your objects that are in the properties? Otherwise, that second comparison could come back with null.
Also, in that second comparison, I'm on the fence about the construct of !( A == B) compared to (A != B), in terms of readability six months/two years from now. The line itself is pretty wide, which is ok if you've got a wide monitor, but might not print out very well. (nitpick)
Are all of your objects always using properties such that this code will work? Could there be some internal, non-propertied data that could be different from one object to another, but all exposed data is the same? I'm thinking of some data which could change over time, like two random number generators that happen to hit the same number at one point, but are going to produce two different sequences of information, or just any data that doesn't get exposed through the property interface.