After a long delay, I finally have 0.8 available for download which
includes the official release of S#arp Architecture using MVC Preview
5, NHibernate 2.0 and Ninject 1.0.
Here is a summary of some of the more significant changes (some
breaking changes) in this release:
* Documentation has been completely updated and much new content has
been added
* ProjectBase has been renamed to SharpArch
* Ninject is now the official mechanism for performing dependency
injection
* The Equals/GetHashCode has been overhauled to be much faster;
additionally, it no longer sees a transient and persistent object as
being the same if their domain signatures are the same
* The basic Equals/GetHashCode logic has been pulled up into the
abstract class SharpArch.Core/DomainSignatureComparable.cs; this may
be used as a base class for non-persistent domain classes to provide
consistent Equals/GetHashCode behavior, e.g. an Address object mapped
as a component of an Employee
* Unit tests have been added to the SharpArch solution; it's not
comprehensive yet, but it's a start
I feel that this is the first major release with a codebase which will
no longer be changing much. Most of the changes which will be coming
in future releases will be upgrades to third party components such as
ASP.NET MVC and NHibernate, inclusion of support for new areas of
functionality such as WCF, and more sample code. So it is my
intention that future releases will have very few breaking changes.
Thanks for the new release. Looks like there are some nice features in there. However, I had written some of my own unit tests on for the previous version and found that 4 of the tests broke with the new release. It seems that when I have two transient objects with the domain signature properties of FirstName and LastName, if I set one objects properties to FName1 and LName1 and a different objects properties to FName2 and LName2, the result is coming back as true when they are compared. If I change the different object property values to something like diffname and difflastname the comparison returns false as expected. Am I writing this test wrong or is this the expected behavior? Here is the Unit Test code that I am using that has brought about the issue. If you change the _diffObj and the _diffObjWithId FirstName and LastName properties the tests will run fine. Thanks again for this great architecture.
Brian
using NUnit.Framework; using SharpArch.Core; using SharpArch.Core.PersistenceSupport;
public class MockPersistentDomainObjectWithSetId : MockPersistentDomainObjectBase<string>, IHasAssignedId<string> { public void SetAssignedIdTo(string assignedId) { ID = assignedId; } }
public class MockPersistentDomainObjectWithDefaultId : MockPersistentDomainObjectBase, IHasAssignedId<int> { public void SetAssignedIdTo(int assignedId) { ID = assignedId; } }
public class MockPersistentDomainObjectBase : MockPersistentDomainObjectBase<int> { }
public class MockPersistentDomainObjectBase<T> : PersistentObjectWithTypedId<T> { [DomainSignature] public string FirstName { get; set; }
[DomainSignature] public string LastName { get; set; }
If I'm not mistaken, the only change that has happened is that now you'll get into domain business signature comparison only if both objects are transient or not (simultaneously)...
> -----Original Message----- > From: sharp-architecture@googlegroups.com [mailto:sharp- > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > Sent: quarta-feira, 1 de Outubro de 2008 18:57 > To: sharp-architecture@googlegroups.com > Subject: Equals and Hashcode question in new release?
> Billy,
> Thanks for the new release. Looks like there are some nice features in > there. However, I had written some of my own unit tests on for the > previous > version and found that 4 of the tests broke with the new release. It > seems > that when I have two transient objects with the domain signature > properties > of FirstName and LastName, if I set one objects properties to FName1 > and > LName1 and a different objects properties to FName2 and LName2, the > result > is coming back as true when they are compared. If I change the > different > object property values to something like diffname and difflastname the > comparison returns false as expected. Am I writing this test wrong or > is > this the expected behavior? Here is the Unit Test code that I am using > that > has brought about the issue. If you change the _diffObj and the > _diffObjWithId FirstName and LastName properties the tests will run > fine. > Thanks again for this great architecture.
> Brian
> using NUnit.Framework; > using SharpArch.Core; > using SharpArch.Core.PersistenceSupport;
That's what I thought too, but these test cases are showing otherwise. They ran fine prior to this release. It seems that the hashcode is returning the same value for the two objects when the domain signatures are off by 1 character. For instance when the FirstName property value is set to FName1 on one object and the property is set to FName2 on the other object, the hashcode is returning the same value.
[mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu Sent: Wednesday, October 01, 2008 1:07 PM To: sharp-architecture@googlegroups.com Subject: RE: Equals and Hashcode question in new release?
Hello.
If I'm not mistaken, the only change that has happened is that now you'll get into domain business signature comparison only if both objects are transient or not (simultaneously)...
-- Luis Abreu
> -----Original Message----- > From: sharp-architecture@googlegroups.com [mailto:sharp- > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > Sent: quarta-feira, 1 de Outubro de 2008 18:57 > To: sharp-architecture@googlegroups.com > Subject: Equals and Hashcode question in new release?
> Billy,
> Thanks for the new release. Looks like there are some nice features in > there. However, I had written some of my own unit tests on for the > previous > version and found that 4 of the tests broke with the new release. It > seems > that when I have two transient objects with the domain signature > properties > of FirstName and LastName, if I set one objects properties to FName1 > and > LName1 and a different objects properties to FName2 and LName2, the > result > is coming back as true when they are compared. If I change the > different > object property values to something like diffname and difflastname the > comparison returns false as expected. Am I writing this test wrong or > is > this the expected behavior? Here is the Unit Test code that I am using > that > has brought about the issue. If you change the _diffObj and the > _diffObjWithId FirstName and LastName properties the tests will run > fine. > Thanks again for this great architecture.
> Brian
> using NUnit.Framework; > using SharpArch.Core; > using SharpArch.Core.PersistenceSupport;
Well, I can see you get a false positive by exchanging values on properties of the same type. Billy, what do you think about this example:
private class ObjectWithIntId2 : PersistentObject { [DomainSignature] public string Name { get; set; } [DomainSignature] public string Address { et; set; }
}
Now, the test:
[Test] public void ShouldBeDifferent() { var obj1 = new ObjectWithIntId2 {Name = "A", Address = "B"}; var obj2 = new ObjectWithIntId2 { Name = "B", Address = "A" }; Assert.That(obj1, Is.Not.EqualTo(obj2));
}
Ok, i think that we need to run equals on the properties instead of using the hashcode. What do you guys think?
> -----Original Message----- > From: sharp-architecture@googlegroups.com [mailto:sharp- > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > Sent: quarta-feira, 1 de Outubro de 2008 19:22 > To: sharp-architecture@googlegroups.com > Subject: RE: Equals and Hashcode question in new release?
> That's what I thought too, but these test cases are showing otherwise. > They > ran fine prior to this release. It seems that the hashcode is > returning the > same value for the two objects when the domain signatures are off by 1 > character. For instance when the FirstName property value is set to > FName1 > on one object and the property is set to FName2 on the other object, > the > hashcode is returning the same value.
> -----Original Message----- > From: sharp-architecture@googlegroups.com > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > Sent: Wednesday, October 01, 2008 1:07 PM > To: sharp-architecture@googlegroups.com > Subject: RE: Equals and Hashcode question in new release?
> Hello.
> If I'm not mistaken, the only change that has happened is that now > you'll > get into domain business signature comparison only if both objects are > transient or not (simultaneously)...
> -- > Luis Abreu
> > -----Original Message----- > > From: sharp-architecture@googlegroups.com [mailto:sharp- > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > > Sent: quarta-feira, 1 de Outubro de 2008 18:57 > > To: sharp-architecture@googlegroups.com > > Subject: Equals and Hashcode question in new release?
> > Billy,
> > Thanks for the new release. Looks like there are some nice features > in > > there. However, I had written some of my own unit tests on for the > > previous > > version and found that 4 of the tests broke with the new release. It > > seems > > that when I have two transient objects with the domain signature > > properties > > of FirstName and LastName, if I set one objects properties to FName1 > > and > > LName1 and a different objects properties to FName2 and LName2, the > > result > > is coming back as true when they are compared. If I change the > > different > > object property values to something like diffname and difflastname > the > > comparison returns false as expected. Am I writing this test wrong or > > is > > this the expected behavior? Here is the Unit Test code that I am > using > > that > > has brought about the issue. If you change the _diffObj and the > > _diffObjWithId FirstName and LastName properties the tests will run > > fine. > > Thanks again for this great architecture.
> > Brian
> > using NUnit.Framework; > > using SharpArch.Core; > > using SharpArch.Core.PersistenceSupport;
I agree with that. I am by no means an expert on how the hash code determines equality, but with your example and the previous one that I uncovered, it seems that there is definitely a problem when comparing 2 objects based on their [DomainSignature] properties.
[mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu Sent: Wednesday, October 01, 2008 3:37 PM To: sharp-architecture@googlegroups.com Subject: RE: Equals and Hashcode question in new release?
Well, I can see you get a false positive by exchanging values on properties of the same type. Billy, what do you think about this example:
private class ObjectWithIntId2 : PersistentObject { [DomainSignature] public string Name { get; set; } [DomainSignature] public string Address { et; set; } }
Now, the test:
[Test] public void ShouldBeDifferent() { var obj1 = new ObjectWithIntId2 {Name = "A", Address = "B"}; var obj2 = new ObjectWithIntId2 { Name = "B", Address = "A" }; Assert.That(obj1, Is.Not.EqualTo(obj2)); }
Ok, i think that we need to run equals on the properties instead of using the hashcode. What do you guys think?
-- Luis Abreu
> -----Original Message----- > From: sharp-architecture@googlegroups.com [mailto:sharp- > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > Sent: quarta-feira, 1 de Outubro de 2008 19:22 > To: sharp-architecture@googlegroups.com > Subject: RE: Equals and Hashcode question in new release?
> That's what I thought too, but these test cases are showing otherwise. > They > ran fine prior to this release. It seems that the hashcode is > returning the > same value for the two objects when the domain signatures are off by 1 > character. For instance when the FirstName property value is set to > FName1 > on one object and the property is set to FName2 on the other object, > the > hashcode is returning the same value.
> -----Original Message----- > From: sharp-architecture@googlegroups.com > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > Sent: Wednesday, October 01, 2008 1:07 PM > To: sharp-architecture@googlegroups.com > Subject: RE: Equals and Hashcode question in new release?
> Hello.
> If I'm not mistaken, the only change that has happened is that now > you'll > get into domain business signature comparison only if both objects are > transient or not (simultaneously)...
> -- > Luis Abreu
> > -----Original Message----- > > From: sharp-architecture@googlegroups.com [mailto:sharp- > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > > Sent: quarta-feira, 1 de Outubro de 2008 18:57 > > To: sharp-architecture@googlegroups.com > > Subject: Equals and Hashcode question in new release?
> > Billy,
> > Thanks for the new release. Looks like there are some nice features > in > > there. However, I had written some of my own unit tests on for the > > previous > > version and found that 4 of the tests broke with the new release. It > > seems > > that when I have two transient objects with the domain signature > > properties > > of FirstName and LastName, if I set one objects properties to FName1 > > and > > LName1 and a different objects properties to FName2 and LName2, the > > result > > is coming back as true when they are compared. If I change the > > different > > object property values to something like diffname and difflastname > the > > comparison returns false as expected. Am I writing this test wrong or > > is > > this the expected behavior? Here is the Unit Test code that I am > using > > that > > has brought about the issue. If you change the _diffObj and the > > _diffObjWithId FirstName and LastName properties the tests will run > > fine. > > Thanks again for this great architecture.
> > Brian
> > using NUnit.Framework; > > using SharpArch.Core; > > using SharpArch.Core.PersistenceSupport;
Yes, but I'm not sure your case is similar to mine. After all, you have 2 different values while I have the same values swapped (which is why I'm getting the wrong result on my test)....
> -----Original Message----- > From: sharp-architecture@googlegroups.com [mailto:sharp- > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > Sent: quarta-feira, 1 de Outubro de 2008 22:10 > To: sharp-architecture@googlegroups.com > Subject: RE: Equals and Hashcode question in new release?
> I agree with that. I am by no means an expert on how the hash code > determines equality, but with your example and the previous one that I > uncovered, it seems that there is definitely a problem when comparing 2 > objects based on their [DomainSignature] properties.
> Brian
> -----Original Message----- > From: sharp-architecture@googlegroups.com > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > Sent: Wednesday, October 01, 2008 3:37 PM > To: sharp-architecture@googlegroups.com > Subject: RE: Equals and Hashcode question in new release?
> Well, I can see you get a false positive by exchanging values on > properties > of the same type. Billy, what do you think about this example:
> private class ObjectWithIntId2 : PersistentObject { > [DomainSignature] > public string Name { get; set; } > [DomainSignature] > public string Address { et; set; } > }
> Now, the test:
> [Test] > public void ShouldBeDifferent() > { > var obj1 = new ObjectWithIntId2 {Name = "A", Address = "B"}; > var obj2 = new ObjectWithIntId2 { Name = "B", Address = "A" }; > Assert.That(obj1, Is.Not.EqualTo(obj2)); > }
> Ok, i think that we need to run equals on the properties instead of > using > the hashcode. What do you guys think?
> -- > Luis Abreu
> > -----Original Message----- > > From: sharp-architecture@googlegroups.com [mailto:sharp- > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > > Sent: quarta-feira, 1 de Outubro de 2008 19:22 > > To: sharp-architecture@googlegroups.com > > Subject: RE: Equals and Hashcode question in new release?
> > That's what I thought too, but these test cases are showing > otherwise. > > They > > ran fine prior to this release. It seems that the hashcode is > > returning the > > same value for the two objects when the domain signatures are off by > 1 > > character. For instance when the FirstName property value is set to > > FName1 > > on one object and the property is set to FName2 on the other object, > > the > > hashcode is returning the same value.
> > -----Original Message----- > > From: sharp-architecture@googlegroups.com > > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > > Sent: Wednesday, October 01, 2008 1:07 PM > > To: sharp-architecture@googlegroups.com > > Subject: RE: Equals and Hashcode question in new release?
> > Hello.
> > If I'm not mistaken, the only change that has happened is that now > > you'll > > get into domain business signature comparison only if both objects > are > > transient or not (simultaneously)...
> > -- > > Luis Abreu
> > > -----Original Message----- > > > From: sharp-architecture@googlegroups.com [mailto:sharp- > > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > > > Sent: quarta-feira, 1 de Outubro de 2008 18:57 > > > To: sharp-architecture@googlegroups.com > > > Subject: Equals and Hashcode question in new release?
> > > Billy,
> > > Thanks for the new release. Looks like there are some nice > features > > in > > > there. However, I had written some of my own unit tests on for the > > > previous > > > version and found that 4 of the tests broke with the new release. > It > > > seems > > > that when I have two transient objects with the domain signature > > > properties > > > of FirstName and LastName, if I set one objects properties to > FName1 > > > and > > > LName1 and a different objects properties to FName2 and LName2, the > > > result > > > is coming back as true when they are compared. If I change the > > > different > > > object property values to something like diffname and difflastname > > the > > > comparison returns false as expected. Am I writing this test wrong > or > > > is > > > this the expected behavior? Here is the Unit Test code that I am > > using > > > that > > > has brought about the issue. If you change the _diffObj and the > > > _diffObjWithId FirstName and LastName properties the tests will run > > > fine. > > > Thanks again for this great architecture.
> > > Brian
> > > using NUnit.Framework; > > > using SharpArch.Core; > > > using SharpArch.Core.PersistenceSupport;
It could be two separate problems I guess. Tracing through my test code points to the same issue with the hash code that you suggested though. Both property values are returning the same hash code when they are similar. It seems that if the code checked for property equality rather than hash code it will work.
[mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu Sent: Wednesday, October 01, 2008 4:30 PM To: sharp-architecture@googlegroups.com Subject: RE: Equals and Hashcode question in new release?
Yes, but I'm not sure your case is similar to mine. After all, you have 2 different values while I have the same values swapped (which is why I'm getting the wrong result on my test)....
-- Luis Abreu
> -----Original Message----- > From: sharp-architecture@googlegroups.com [mailto:sharp- > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > Sent: quarta-feira, 1 de Outubro de 2008 22:10 > To: sharp-architecture@googlegroups.com > Subject: RE: Equals and Hashcode question in new release?
> I agree with that. I am by no means an expert on how the hash code > determines equality, but with your example and the previous one that I > uncovered, it seems that there is definitely a problem when comparing 2 > objects based on their [DomainSignature] properties.
> Brian
> -----Original Message----- > From: sharp-architecture@googlegroups.com > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > Sent: Wednesday, October 01, 2008 3:37 PM > To: sharp-architecture@googlegroups.com > Subject: RE: Equals and Hashcode question in new release?
> Well, I can see you get a false positive by exchanging values on > properties > of the same type. Billy, what do you think about this example:
> private class ObjectWithIntId2 : PersistentObject { > [DomainSignature] > public string Name { get; set; } > [DomainSignature] > public string Address { et; set; } > }
> Now, the test:
> [Test] > public void ShouldBeDifferent() > { > var obj1 = new ObjectWithIntId2 {Name = "A", Address = "B"}; > var obj2 = new ObjectWithIntId2 { Name = "B", Address = "A" }; > Assert.That(obj1, Is.Not.EqualTo(obj2)); > }
> Ok, i think that we need to run equals on the properties instead of > using > the hashcode. What do you guys think?
> -- > Luis Abreu
> > -----Original Message----- > > From: sharp-architecture@googlegroups.com [mailto:sharp- > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > > Sent: quarta-feira, 1 de Outubro de 2008 19:22 > > To: sharp-architecture@googlegroups.com > > Subject: RE: Equals and Hashcode question in new release?
> > That's what I thought too, but these test cases are showing > otherwise. > > They > > ran fine prior to this release. It seems that the hashcode is > > returning the > > same value for the two objects when the domain signatures are off by > 1 > > character. For instance when the FirstName property value is set to > > FName1 > > on one object and the property is set to FName2 on the other object, > > the > > hashcode is returning the same value.
> > -----Original Message----- > > From: sharp-architecture@googlegroups.com > > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > > Sent: Wednesday, October 01, 2008 1:07 PM > > To: sharp-architecture@googlegroups.com > > Subject: RE: Equals and Hashcode question in new release?
> > Hello.
> > If I'm not mistaken, the only change that has happened is that now > > you'll > > get into domain business signature comparison only if both objects > are > > transient or not (simultaneously)...
> > -- > > Luis Abreu
> > > -----Original Message----- > > > From: sharp-architecture@googlegroups.com [mailto:sharp- > > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > > > Sent: quarta-feira, 1 de Outubro de 2008 18:57 > > > To: sharp-architecture@googlegroups.com > > > Subject: Equals and Hashcode question in new release?
> > > Billy,
> > > Thanks for the new release. Looks like there are some nice > features > > in > > > there. However, I had written some of my own unit tests on for the > > > previous > > > version and found that 4 of the tests broke with the new release. > It > > > seems > > > that when I have two transient objects with the domain signature > > > properties > > > of FirstName and LastName, if I set one objects properties to > FName1 > > > and > > > LName1 and a different objects properties to FName2 and LName2, the > > > result > > > is coming back as true when they are compared. If I change the > > > different > > > object property values to something like diffname and difflastname > > the > > > comparison returns false as expected. Am I writing this test wrong > or > > > is > > > this the expected behavior? Here is the Unit Test code that I am > > using > > > that > > > has brought about the issue. If you change the _diffObj and the > > > _diffObjWithId FirstName and LastName properties the tests will run > > > fine. > > > Thanks again for this great architecture.
> > > Brian
> > > using NUnit.Framework; > > > using SharpArch.Core; > > > using SharpArch.Core.PersistenceSupport;
Hum...that is interesting...I mean, in my case, it was obvious I'd get the same hash because I?ve just exchanged the properties' values, but in yours you had different values (ie, you f1/l1 and then f2/l2 - or something along these lines). I expected that the hashcode for these would always be different, but again, I might be wrong.
> -----Original Message----- > From: sharp-architecture@googlegroups.com [mailto:sharp- > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > Sent: quarta-feira, 1 de Outubro de 2008 22:48 > To: sharp-architecture@googlegroups.com > Subject: RE: Equals and Hashcode question in new release?
> It could be two separate problems I guess. Tracing through my test > code > points to the same issue with the hash code that you suggested though. > Both > property values are returning the same hash code when they are similar. > It > seems that if the code checked for property equality rather than hash > code > it will work.
> -----Original Message----- > From: sharp-architecture@googlegroups.com > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > Sent: Wednesday, October 01, 2008 4:30 PM > To: sharp-architecture@googlegroups.com > Subject: RE: Equals and Hashcode question in new release?
> Yes, but I'm not sure your case is similar to mine. After all, you have > 2 > different values while I have the same values swapped (which is why I'm > getting the wrong result on my test)....
> -- > Luis Abreu
> > -----Original Message----- > > From: sharp-architecture@googlegroups.com [mailto:sharp- > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > > Sent: quarta-feira, 1 de Outubro de 2008 22:10 > > To: sharp-architecture@googlegroups.com > > Subject: RE: Equals and Hashcode question in new release?
> > I agree with that. I am by no means an expert on how the hash code > > determines equality, but with your example and the previous one that > I > > uncovered, it seems that there is definitely a problem when comparing > 2 > > objects based on their [DomainSignature] properties.
> > Brian
> > -----Original Message----- > > From: sharp-architecture@googlegroups.com > > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > > Sent: Wednesday, October 01, 2008 3:37 PM > > To: sharp-architecture@googlegroups.com > > Subject: RE: Equals and Hashcode question in new release?
> > Well, I can see you get a false positive by exchanging values on > > properties > > of the same type. Billy, what do you think about this example:
> > private class ObjectWithIntId2 : PersistentObject { > > [DomainSignature] > > public string Name { get; set; } > > [DomainSignature] > > public string Address { et; set; } > > }
> > Now, the test:
> > [Test] > > public void ShouldBeDifferent() > > { > > var obj1 = new ObjectWithIntId2 {Name = "A", Address = "B"}; > > var obj2 = new ObjectWithIntId2 { Name = "B", Address = "A" }; > > Assert.That(obj1, Is.Not.EqualTo(obj2)); > > }
> > Ok, i think that we need to run equals on the properties instead of > > using > > the hashcode. What do you guys think?
> > -- > > Luis Abreu
> > > -----Original Message----- > > > From: sharp-architecture@googlegroups.com [mailto:sharp- > > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > > > Sent: quarta-feira, 1 de Outubro de 2008 19:22 > > > To: sharp-architecture@googlegroups.com > > > Subject: RE: Equals and Hashcode question in new release?
> > > That's what I thought too, but these test cases are showing > > otherwise. > > > They > > > ran fine prior to this release. It seems that the hashcode is > > > returning the > > > same value for the two objects when the domain signatures are off > by > > 1 > > > character. For instance when the FirstName property value is set to > > > FName1 > > > on one object and the property is set to FName2 on the other > object, > > > the > > > hashcode is returning the same value.
> > > -----Original Message----- > > > From: sharp-architecture@googlegroups.com > > > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis > Abreu > > > Sent: Wednesday, October 01, 2008 1:07 PM > > > To: sharp-architecture@googlegroups.com > > > Subject: RE: Equals and Hashcode question in new release?
> > > Hello.
> > > If I'm not mistaken, the only change that has happened is that now > > > you'll > > > get into domain business signature comparison only if both objects > > are > > > transient or not (simultaneously)...
> > > -- > > > Luis Abreu
> > > > -----Original Message----- > > > > From: sharp-architecture@googlegroups.com [mailto:sharp- > > > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > > > > Sent: quarta-feira, 1 de Outubro de 2008 18:57 > > > > To: sharp-architecture@googlegroups.com > > > > Subject: Equals and Hashcode question in new release?
> > > > Billy,
> > > > Thanks for the new release. Looks like there are some nice > > features > > > in > > > > there. However, I had written some of my own unit tests on for > the > > > > previous > > > > version and found that 4 of the tests broke with the new release. > > It > > > > seems > > > > that when I have two transient objects with the domain signature > > > > properties > > > > of FirstName and LastName, if I set one objects properties to > > FName1 > > > > and > > > > LName1 and a different objects properties to FName2 and LName2, > the > > > > result > > > > is coming back as true when they are compared. If I change the > > > > different > > > > object property values to something like diffname and > difflastname > > > the > > > > comparison returns false as expected. Am I writing this test > wrong > > or > > > > is > > > > this the expected behavior? Here is the Unit Test code that I am > > > using > > > > that > > > > has brought about the issue. If you change the _diffObj and the > > > > _diffObjWithId FirstName and LastName properties the tests will > run > > > > fine. > > > > Thanks again for this great architecture.
> > > > Brian
> > > > using NUnit.Framework; > > > > using SharpArch.Core; > > > > using SharpArch.Core.PersistenceSupport;
Yes, that was my assumption of the way that the hash code worked as well. But, running the test through the debugger brings up the same HashCode in the GetDomainObjectSignature() method for the following objects where FirstName and LastName are the combined DomainSignature for the class.
[mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu Sent: Wednesday, October 01, 2008 4:51 PM To: sharp-architecture@googlegroups.com Subject: RE: Equals and Hashcode question in new release?
Hum...that is interesting...I mean, in my case, it was obvious I'd get the same hash because I?ve just exchanged the properties' values, but in yours you had different values (ie, you f1/l1 and then f2/l2 - or something along these lines). I expected that the hashcode for these would always be different, but again, I might be wrong.
-- Luis Abreu
> -----Original Message----- > From: sharp-architecture@googlegroups.com [mailto:sharp- > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > Sent: quarta-feira, 1 de Outubro de 2008 22:48 > To: sharp-architecture@googlegroups.com > Subject: RE: Equals and Hashcode question in new release?
> It could be two separate problems I guess. Tracing through my test > code > points to the same issue with the hash code that you suggested though. > Both > property values are returning the same hash code when they are similar. > It > seems that if the code checked for property equality rather than hash > code > it will work.
> -----Original Message----- > From: sharp-architecture@googlegroups.com > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > Sent: Wednesday, October 01, 2008 4:30 PM > To: sharp-architecture@googlegroups.com > Subject: RE: Equals and Hashcode question in new release?
> Yes, but I'm not sure your case is similar to mine. After all, you have > 2 > different values while I have the same values swapped (which is why I'm > getting the wrong result on my test)....
> -- > Luis Abreu
> > -----Original Message----- > > From: sharp-architecture@googlegroups.com [mailto:sharp- > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > > Sent: quarta-feira, 1 de Outubro de 2008 22:10 > > To: sharp-architecture@googlegroups.com > > Subject: RE: Equals and Hashcode question in new release?
> > I agree with that. I am by no means an expert on how the hash code > > determines equality, but with your example and the previous one that > I > > uncovered, it seems that there is definitely a problem when comparing > 2 > > objects based on their [DomainSignature] properties.
> > Brian
> > -----Original Message----- > > From: sharp-architecture@googlegroups.com > > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > > Sent: Wednesday, October 01, 2008 3:37 PM > > To: sharp-architecture@googlegroups.com > > Subject: RE: Equals and Hashcode question in new release?
> > Well, I can see you get a false positive by exchanging values on > > properties > > of the same type. Billy, what do you think about this example:
> > private class ObjectWithIntId2 : PersistentObject { > > [DomainSignature] > > public string Name { get; set; } > > [DomainSignature] > > public string Address { et; set; } > > }
> > Now, the test:
> > [Test] > > public void ShouldBeDifferent() > > { > > var obj1 = new ObjectWithIntId2 {Name = "A", Address = "B"}; > > var obj2 = new ObjectWithIntId2 { Name = "B", Address = "A" }; > > Assert.That(obj1, Is.Not.EqualTo(obj2)); > > }
> > Ok, i think that we need to run equals on the properties instead of > > using > > the hashcode. What do you guys think?
> > -- > > Luis Abreu
> > > -----Original Message----- > > > From: sharp-architecture@googlegroups.com [mailto:sharp- > > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > > > Sent: quarta-feira, 1 de Outubro de 2008 19:22 > > > To: sharp-architecture@googlegroups.com > > > Subject: RE: Equals and Hashcode question in new release?
> > > That's what I thought too, but these test cases are showing > > otherwise. > > > They > > > ran fine prior to this release. It seems that the hashcode is > > > returning the > > > same value for the two objects when the domain signatures are off > by > > 1 > > > character. For instance when the FirstName property value is set to > > > FName1 > > > on one object and the property is set to FName2 on the other > object, > > > the > > > hashcode is returning the same value.
> > > -----Original Message----- > > > From: sharp-architecture@googlegroups.com > > > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis > Abreu > > > Sent: Wednesday, October 01, 2008 1:07 PM > > > To: sharp-architecture@googlegroups.com > > > Subject: RE: Equals and Hashcode question in new release?
> > > Hello.
> > > If I'm not mistaken, the only change that has happened is that now > > > you'll > > > get into domain business signature comparison only if both objects > > are > > > transient or not (simultaneously)...
> > > -- > > > Luis Abreu
> > > > -----Original Message----- > > > > From: sharp-architecture@googlegroups.com [mailto:sharp- > > > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > > > > Sent: quarta-feira, 1 de Outubro de 2008 18:57 > > > > To: sharp-architecture@googlegroups.com > > > > Subject: Equals and Hashcode question in new release?
> > > > Billy,
> > > > Thanks for the new release. Looks like there are some nice > > features > > > in > > > > there. However, I had written some of my own unit tests on for > the > > > > previous > > > > version and found that 4 of the tests broke with the new release. > > It > > > > seems > > > > that when I have two transient objects with the domain signature > > > > properties > > > > of FirstName and LastName, if I set one objects properties to > > FName1 > > > > and > > > > LName1 and a different objects properties to FName2 and LName2, > the > > > > result > > > > is coming back as true when they are compared. If I change the > > > > different > > > > object property values to something like diffname and > difflastname > > > the > > > > comparison returns false as expected. Am I writing this test > wrong > > or > > > > is > > > > this the expected behavior? Here is the Unit Test code that I am > > > using > > > > that > > > > has brought about the issue. If you change the _diffObj and the > > > > _diffObjWithId FirstName and LastName properties the tests will > run > > > > fine. > > > > Thanks again for this great architecture.
> > > > Brian
> > > > using NUnit.Framework; > > > > using SharpArch.Core; > > > > using SharpArch.Core.PersistenceSupport;
incredible...I've just run some powershell tests and yes, you're correct. Interestingly, each string has its own integer value but when youo combine them with ^operator you get the same result...
so, we do need some way to corretly implement hascode...anyone good with math?
On Wed, Oct 1, 2008 at 11:11 PM, Brian Nicoloff <nicol...@sbcglobal.net> wrote:
> Yes, that was my assumption of the way that the hash code worked as well. > But, running the test through the debugger brings up the same HashCode in > the GetDomainObjectSignature() method for the following objects where > FirstName and LastName are the combined DomainSignature for the class.
> -----Original Message----- > From: sharp-architecture@googlegroups.com > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > Sent: Wednesday, October 01, 2008 4:51 PM > To: sharp-architecture@googlegroups.com > Subject: RE: Equals and Hashcode question in new release?
> Hum...that is interesting...I mean, in my case, it was obvious I'd get the > same hash because I?ve just exchanged the properties' values, but in yours > you had different values (ie, you f1/l1 and then f2/l2 - or something along > these lines). I expected that the hashcode for these would always be > different, but again, I might be wrong.
> -- > Luis Abreu
>> -----Original Message----- >> From: sharp-architecture@googlegroups.com [mailto:sharp- >> architecture@googlegroups.com] On Behalf Of Brian Nicoloff >> Sent: quarta-feira, 1 de Outubro de 2008 22:48 >> To: sharp-architecture@googlegroups.com >> Subject: RE: Equals and Hashcode question in new release?
>> It could be two separate problems I guess. Tracing through my test >> code >> points to the same issue with the hash code that you suggested though. >> Both >> property values are returning the same hash code when they are similar. >> It >> seems that if the code checked for property equality rather than hash >> code >> it will work.
>> -----Original Message----- >> From: sharp-architecture@googlegroups.com >> [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu >> Sent: Wednesday, October 01, 2008 4:30 PM >> To: sharp-architecture@googlegroups.com >> Subject: RE: Equals and Hashcode question in new release?
>> Yes, but I'm not sure your case is similar to mine. After all, you have >> 2 >> different values while I have the same values swapped (which is why I'm >> getting the wrong result on my test)....
>> -- >> Luis Abreu
>> > -----Original Message----- >> > From: sharp-architecture@googlegroups.com [mailto:sharp- >> > architecture@googlegroups.com] On Behalf Of Brian Nicoloff >> > Sent: quarta-feira, 1 de Outubro de 2008 22:10 >> > To: sharp-architecture@googlegroups.com >> > Subject: RE: Equals and Hashcode question in new release?
>> > I agree with that. I am by no means an expert on how the hash code >> > determines equality, but with your example and the previous one that >> I >> > uncovered, it seems that there is definitely a problem when comparing >> 2 >> > objects based on their [DomainSignature] properties.
>> > Brian
>> > -----Original Message----- >> > From: sharp-architecture@googlegroups.com >> > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu >> > Sent: Wednesday, October 01, 2008 3:37 PM >> > To: sharp-architecture@googlegroups.com >> > Subject: RE: Equals and Hashcode question in new release?
>> > Well, I can see you get a false positive by exchanging values on >> > properties >> > of the same type. Billy, what do you think about this example:
>> > private class ObjectWithIntId2 : PersistentObject { >> > [DomainSignature] >> > public string Name { get; set; } >> > [DomainSignature] >> > public string Address { et; set; } >> > }
>> > Now, the test:
>> > [Test] >> > public void ShouldBeDifferent() >> > { >> > var obj1 = new ObjectWithIntId2 {Name = "A", Address = "B"}; >> > var obj2 = new ObjectWithIntId2 { Name = "B", Address = "A" }; >> > Assert.That(obj1, Is.Not.EqualTo(obj2)); >> > }
>> > Ok, i think that we need to run equals on the properties instead of >> > using >> > the hashcode. What do you guys think?
>> > -- >> > Luis Abreu
>> > > -----Original Message----- >> > > From: sharp-architecture@googlegroups.com [mailto:sharp- >> > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff >> > > Sent: quarta-feira, 1 de Outubro de 2008 19:22 >> > > To: sharp-architecture@googlegroups.com >> > > Subject: RE: Equals and Hashcode question in new release?
>> > > That's what I thought too, but these test cases are showing >> > otherwise. >> > > They >> > > ran fine prior to this release. It seems that the hashcode is >> > > returning the >> > > same value for the two objects when the domain signatures are off >> by >> > 1 >> > > character. For instance when the FirstName property value is set to >> > > FName1 >> > > on one object and the property is set to FName2 on the other >> object, >> > > the >> > > hashcode is returning the same value.
>> > > -----Original Message----- >> > > From: sharp-architecture@googlegroups.com >> > > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis >> Abreu >> > > Sent: Wednesday, October 01, 2008 1:07 PM >> > > To: sharp-architecture@googlegroups.com >> > > Subject: RE: Equals and Hashcode question in new release?
>> > > Hello.
>> > > If I'm not mistaken, the only change that has happened is that now >> > > you'll >> > > get into domain business signature comparison only if both objects >> > are >> > > transient or not (simultaneously)...
>> > > -- >> > > Luis Abreu
>> > > > -----Original Message----- >> > > > From: sharp-architecture@googlegroups.com [mailto:sharp- >> > > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff >> > > > Sent: quarta-feira, 1 de Outubro de 2008 18:57 >> > > > To: sharp-architecture@googlegroups.com >> > > > Subject: Equals and Hashcode question in new release?
>> > > > Billy,
>> > > > Thanks for the new release. Looks like there are some nice >> > features >> > > in >> > > > there. However, I had written some of my own unit tests on for >> the >> > > > previous >> > > > version and found that 4 of the tests broke with the new release. >> > It >> > > > seems >> > > > that when I have two transient objects with the domain signature >> > > > properties >> > > > of FirstName and LastName, if I set one objects properties to >> > FName1 >> > > > and >> > > > LName1 and a different objects properties to FName2 and LName2, >> the >> > > > result >> > > > is coming back as true when they are compared. If I change the >> > > > different >> > > > object property values to something like diffname and >> difflastname >> > > the >> > > > comparison returns false as expected. Am I writing this test >> wrong >> > or >> > > > is >> > > > this the expected behavior? Here is the Unit Test code that I am >> > > using >> > > > that >> > > > has brought about the issue. If you change the _diffObj and the >> > > > _diffObjWithId FirstName and LastName properties the tests will >> run >> > > > fine. >> > > > Thanks again for this great architecture.
>> > > > Brian
>> > > > using NUnit.Framework; >> > > > using SharpArch.Core; >> > > > using SharpArch.Core.PersistenceSupport;
The nasty properties of XOR are: It treats identical pairs of components as if they were not there.
It ignores order. A ^ B is the same a B ^ A. If order matters, you want
some sort of checksum/digest such as Adlerian. XOR would not be suitable
to compute the hashCode for a List which depends on the order of the
elements as part of its identity.
If the values to be combined are only 8 bits wide, there will be
effectively only 8 bits in the xored result. In contrast, multiplying by
a prime and adding would scramble the entire 32 bits of the result,
giving a much broader range of possible values, hence greater chance
that each hashcode will unique to a single Object. In other words, it
tends to expand the range of the digest into the widest possible band
(32 bits).
[mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu
Sent: 02 October 2008 10:27
To: sharp-architecture@googlegroups.com
Subject: Re: Equals and Hashcode question in new release?
incredible...I've just run some powershell tests and yes, you're
correct. Interestingly, each string has its own integer value but when
youo combine them with ^operator you get the same result...
so, we do need some way to corretly implement hascode...anyone good with
math?
On Wed, Oct 1, 2008 at 11:11 PM, Brian Nicoloff <nicol...@sbcglobal.net>
wrote:
> Yes, that was my assumption of the way that the hash code worked as
well.
> But, running the test through the debugger brings up the same HashCode
in
> the GetDomainObjectSignature() method for the following objects where
> FirstName and LastName are the combined DomainSignature for the class.
> -----Original Message-----
> From: sharp-architecture@googlegroups.com
> [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu
> Sent: Wednesday, October 01, 2008 4:51 PM
> To: sharp-architecture@googlegroups.com
> Subject: RE: Equals and Hashcode question in new release?
> Hum...that is interesting...I mean, in my case, it was obvious I'd get
the
> same hash because I?ve just exchanged the properties' values, but in
yours
> you had different values (ie, you f1/l1 and then f2/l2 - or something
along
> these lines). I expected that the hashcode for these would always be
> different, but again, I might be wrong.
> --
> Luis Abreu
>> -----Original Message-----
>> From: sharp-architecture@googlegroups.com [mailto:sharp-
>> architecture@googlegroups.com] On Behalf Of Brian Nicoloff
>> Sent: quarta-feira, 1 de Outubro de 2008 22:48
>> To: sharp-architecture@googlegroups.com
>> Subject: RE: Equals and Hashcode question in new release?
>> It could be two separate problems I guess. Tracing through my test
>> code
>> points to the same issue with the hash code that you suggested
though.
>> Both
>> property values are returning the same hash code when they are
similar.
>> It
>> seems that if the code checked for property equality rather than hash
>> code
>> it will work.
>> -----Original Message-----
>> From: sharp-architecture@googlegroups.com
>> [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu
>> Sent: Wednesday, October 01, 2008 4:30 PM
>> To: sharp-architecture@googlegroups.com
>> Subject: RE: Equals and Hashcode question in new release?
>> Yes, but I'm not sure your case is similar to mine. After all, you
have
>> 2
>> different values while I have the same values swapped (which is why
I'm
>> getting the wrong result on my test)....
>> --
>> Luis Abreu
>> > -----Original Message-----
>> > From: sharp-architecture@googlegroups.com [mailto:sharp-
>> > architecture@googlegroups.com] On Behalf Of Brian Nicoloff
>> > Sent: quarta-feira, 1 de Outubro de 2008 22:10
>> > To: sharp-architecture@googlegroups.com
>> > Subject: RE: Equals and Hashcode question in new release?
>> > I agree with that. I am by no means an expert on how the hash code
>> > determines equality, but with your example and the previous one
that
>> I
>> > uncovered, it seems that there is definitely a problem when
comparing
>> 2
>> > objects based on their [DomainSignature] properties.
>> > Brian
>> > -----Original Message-----
>> > From: sharp-architecture@googlegroups.com
>> > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis
Abreu
>> > Sent: Wednesday, October 01, 2008 3:37 PM
>> > To: sharp-architecture@googlegroups.com
>> > Subject: RE: Equals and Hashcode question in new release?
>> > Well, I can see you get a false positive by exchanging values on
>> > properties
>> > of the same type. Billy, what do you think about this example:
>> > private class ObjectWithIntId2 : PersistentObject {
>> > [DomainSignature]
>> > public string Name { get; set; }
>> > [DomainSignature]
>> > public string Address { et; set; }
>> > }
>> > Now, the test:
>> > [Test]
>> > public void ShouldBeDifferent()
>> > {
>> > var obj1 = new ObjectWithIntId2 {Name = "A", Address = "B"};
>> > var obj2 = new ObjectWithIntId2 { Name = "B", Address = "A" };
>> > Assert.That(obj1, Is.Not.EqualTo(obj2));
>> > }
>> > Ok, i think that we need to run equals on the properties instead of
>> > using
>> > the hashcode. What do you guys think?
>> > --
>> > Luis Abreu
>> > > -----Original Message-----
>> > > From: sharp-architecture@googlegroups.com [mailto:sharp-
>> > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff
>> > > Sent: quarta-feira, 1 de Outubro de 2008 19:22
>> > > To: sharp-architecture@googlegroups.com
>> > > Subject: RE: Equals and Hashcode question in new release?
>> > > That's what I thought too, but these test cases are showing
>> > otherwise.
>> > > They
>> > > ran fine prior to this release. It seems that the hashcode is
>> > > returning the
>> > > same value for the two objects when the domain signatures are off
>> by
>> > 1
>> > > character. For instance when the FirstName property value is set
to
>> > > FName1
>> > > on one object and the property is set to FName2 on the other
>> object,
>> > > the
>> > > hashcode is returning the same value.
>> > > -----Original Message-----
>> > > From: sharp-architecture@googlegroups.com
>> > > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis
>> Abreu
>> > > Sent: Wednesday, October 01, 2008 1:07 PM
>> > > To: sharp-architecture@googlegroups.com
>> > > Subject: RE: Equals and Hashcode question in new release?
>> > > Hello.
>> > > If I'm not mistaken, the only change that has happened is that
now
>> > > you'll
>> > > get into domain business signature comparison only if both
objects
>> > are
>> > > transient or not (simultaneously)...
>> > > --
>> > > Luis Abreu
>> > > > -----Original Message-----
>> > > > From: sharp-architecture@googlegroups.com [mailto:sharp-
>> > > > architecture@googlegroups.com] On Behalf Of Brian Nicoloff
>> > > > Sent: quarta-feira, 1 de Outubro de 2008 18:57
>> > > > To: sharp-architecture@googlegroups.com
>> > > > Subject: Equals and Hashcode question in new release?
>> > > > Billy,
>> > > > Thanks for the new release. Looks like there are some nice
>> > features
>> > > in
>> > > > there. However, I had written some of my own unit tests on for
>> the
>> > > > previous
>> > > > version and found that 4 of the tests broke with the new
release.
>> > It
>> > > > seems
>> > > > that when I have two transient objects with the domain
signature
>> > > > properties
>> > > > of FirstName and LastName, if I set one objects properties to
>> > FName1
>> > > > and
>> > > > LName1 and a different objects properties to FName2 and LName2,
>> the
>> > > > result
>> > > > is coming back as true when they are compared. If I change the
>> > > > different
>> > > > object property values to something like diffname and
>> difflastname
>> > > the
>> > > > comparison returns false as expected. Am I writing this test
>> wrong
>> > or
>> > > > is
>> > > > this the expected behavior? Here is the Unit Test code that I
am
>> > > using
>> > > > that
>> > > > has brought about the issue. If you change the _diffObj and the
>> > > > _diffObjWithId FirstName and LastName properties the tests will
>> run
>> > > > fine.
>> > > > Thanks again for this great architecture.
>> > > > Brian
>> > > > using NUnit.Framework;
>> > > > using SharpArch.Core;
>> > > > using SharpArch.Core.PersistenceSupport;
I guess that the problem is that we're thinking about the GetHashcode method incorrectly. Ok, if 2 objects are equal, the hashcode must be equal, but if two objects are different, there's nothing out there that says that they must return a different hashcode! So, the problem here is that we're using the hascode for equality when we shouldn't be doing that. Even with a fancy algorythm, there's always the chance of having 2 "different" objects returning the same hashcode.
So, I'd really prefer to add a method that compares properties instead of relying in hashcode. For instance, adding a method like this:
and, of course, the Equals method oe PersistentObject to:
public override bool Equals(object obj) { PersistentObjectWithTypedId<IdT> compareTo = obj as PersistentObjectWithTypedId<IdT>;
return compareTo != null && (HasSameNonDefaultIdAs(compareTo) || // Since the IDs aren't the same, both of them must be transient to // compare business value signatures. If one is transient and the other is // a persisted entity, then they cannot be the same object. (((IsTransient()) && compareTo.IsTransient()) && DoObjectsHaveSomeBusinessSignature(compareTo))); }
Ok, this breaks the domainscignaturecomparable tests (only!). no doubt about it. However. i believe that this is a good thing because I'm not sure about these tests. For instance, the CanCompareDomainObjectsWithOnlySomePropertiesBeingPartOfDomainSignature looks like this:
public void CanCompareDomainObjectsWithOnlySomePropertiesBeingPartOfDomainSignature() { ObjectWithOneDomainSignatureProperty object1 = new ObjectWithOneDomainSignatureProperty(); ObjectWithOneDomainSignatureProperty object2 = new ObjectWithOneDomainSignatureProperty(); Assert.That(object1, Is.Not.EqualTo(object2));
object1.Age = 13; object2.Age = 13; // Name property isn't included in comparison object1.Name = "Foo"; object2.Name = "Bar"; Assert.That(object1, Is.EqualTo(object2));
Now, why do we have the first assertion? I mean, DomainSignatureComparable does not have the concept of transitory objects. So, I think that the 1st Assert is wrong. Here's how I expect this class to behave:
1. if there isn't any property anotated with the domainsignature attribute, then I expect it to return false (always). I assume this because in this case equality is synonim of having the same values applied to predefined properties. Ok, there's one case where I think some debate is in order: what if we have two references to the same object of a type that doesn't has any property used in the domain signature? Ideas? Btw, it could be useful to optimize the code by using Object.ReferenceEquals in my previous code suggestion. if it returns true, then there's no need of going throught reflection, right? 2. if the class does have domain signature properties, then the equality should be true if all those properties have the same value. Now, if you look at the previous test, that is true: the age property is part of the signature and since the class doesn't has the concept of transient (delegate to the persistenobjectXXX class), then that assert shouldn't hold. ie, two new instances will get the same value for their ID, which means that they should be equal. Note that I'm talking about the domainsignaturecomparable class, not anout the persistenobjectXXX class. If the DomainSignatureComparable class had the notion of transient object, then I would expect that assert to hold...
> The nasty properties of XOR are: > It treats identical pairs of components as if they were not there. > It ignores order. A ^ B is the same a B ^ A. If order matters, you want > some sort of checksum/digest such as Adlerian. XOR would not be suitable > to compute the hashCode for a List which depends on the order of the > elements as part of its identity. > If the values to be combined are only 8 bits wide, there will be > effectively only 8 bits in the xored result. In contrast, multiplying by > a prime and adding would scramble the entire 32 bits of the result, > giving a much broader range of possible values, hence greater chance > that each hashcode will unique to a single Object. In other words, it > tends to expand the range of the digest into the widest possible band > (32 bits).
> There are some examples of implementation.
> Hope it helps
> Martin
> -----Original Message----- > From: sharp-architecture@googlegroups.com > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > Sent: 02 October 2008 10:27 > To: sharp-architecture@googlegroups.com > Subject: Re: Equals and Hashcode question in new release?
> incredible...I've just run some powershell tests and yes, you're > correct. Interestingly, each string has its own integer value but when > youo combine them with ^operator you get the same result...
> so, we do need some way to corretly implement hascode...anyone good with > math?
> On Wed, Oct 1, 2008 at 11:11 PM, Brian Nicoloff <nicol...@sbcglobal.net> > wrote:
>> Yes, that was my assumption of the way that the hash code worked as > well. >> But, running the test through the debugger brings up the same HashCode > in >> the GetDomainObjectSignature() method for the following objects where >> FirstName and LastName are the combined DomainSignature for the class.
>> -----Original Message----- >> From: sharp-architecture@googlegroups.com >> [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu >> Sent: Wednesday, October 01, 2008 4:51 PM >> To: sharp-architecture@googlegroups.com >> Subject: RE: Equals and Hashcode question in new release?
>> Hum...that is interesting...I mean, in my case, it was obvious I'd get > the >> same hash because I?ve just exchanged the properties' values, but in > yours >> you had different values (ie, you f1/l1 and then f2/l2 - or something > along >> these lines). I expected that the hashcode for these would always be >> different, but again, I might be wrong.
>> -- >> Luis Abreu
>>> -----Original Message----- >>> From: sharp-architecture@googlegroups.com [mailto:sharp- >>> architecture@googlegroups.com] On Behalf Of Brian Nicoloff >>> Sent: quarta-feira, 1 de Outubro de 2008 22:48 >>> To: sharp-architecture@googlegroups.com >>> Subject: RE: Equals and Hashcode question in new release?
>>> It could be two separate problems I guess. Tracing through my test >>> code >>> points to the same issue with the hash code that you suggested > though. >>> Both >>> property values are returning the same hash code when they are > similar. >>> It >>> seems that if the code checked for property equality rather than hash >>> code >>> it will work.
>>> -----Original Message----- >>> From: sharp-architecture@googlegroups.com >>> [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu >>> Sent: Wednesday, October 01, 2008 4:30 PM >>> To: sharp-architecture@googlegroups.com >>> Subject: RE: Equals and Hashcode question in new release?
>>> Yes, but I'm not sure your case is similar to mine. After all, you > have >>> 2 >>> different values while I have the same values swapped (which is why > I'm >>> getting the wrong result on my test)....
>>> -- >>> Luis Abreu
>>> > -----Original Message----- >>> > From: sharp-architecture@googlegroups.com [mailto:sharp- >>> > architecture@googlegroups.com] On Behalf Of Brian Nicoloff >>> > Sent: quarta-feira, 1 de Outubro de 2008 22:10 >>> > To: sharp-architecture@googlegroups.com >>> > Subject: RE: Equals and Hashcode question in new release?
>>> > I agree with that. I am by no means an expert on how the hash code >>> > determines equality, but with your example and the previous one > that >>> I >>> > uncovered, it seems that there is definitely a problem when > comparing >>> 2 >>> > objects based
/// <summary> /// Used to compare two objects via <see cref="Equals"/>; although it's necessary for /// NHibernate's use, this may also be useful for business logic purposes. /// </summary> public override int GetHashCode() { // Since it's possible for two objects to return the same domain signature, // even if they're of two different types, it's important to include the object's // type in the domain signature return GetType().GetHashCode() ^ GetDomainObjectSignature(); }
/// <summary> /// The method GetDomainObjectSignature should ONLY return the "business value /// signature" of the object and not the ID, which is handled by <see cref="PersistentObject" />. /// /// If you choose NOT to override this method, then you should decorate the appropriate /// property(s) with [DomainSignature] and they will be compared automatically. Using the /// [DomainSignature] attribute is the preferred method. /// /// Alternatively, if you override this method, the general structure of the overridden method /// should be as follows: /// /// return SomeProperty.GetHashCode() ^ SomeOtherProperty.GetHashCode(); /// /// </summary> protected virtual int GetDomainObjectSignature() { var domainObjectSignature = 0;
foreach (var property in GetType().GetProperties()) { if (!IsPartOfDomainSignature(property)) { continue; } var value = property.GetValue(this, null);
// If no properties were flagged as being part of the domain signature of the object, // then simply return the hashcode of the base object as the domain signature. This // behaves as you would normally expect Equals to behave when comparing two objects. return domainObjectSignature == 0 ? base.GetHashCode() : domainObjectSignature; }
protected bool DoObjectsHaveSomeBusinessSignature(DomainSignatureComparable to) { var hasDomainSignatureSpecified = false; foreach (var property in GetType().GetProperties()) { if (!IsPartOfDomainSignature(property)) { continue; } hasDomainSignatureSpecified = true; var value = property.GetValue(this, null); var anotherValue = property.GetValue(to, null); if(ReferenceEquals(value, anotherValue) ) return true; if( value == null || anotherValue == null) return false; if (!value.Equals(anotherValue)) { return false; } } return true & hasDomainSignatureSpecified; }
On Thu, Oct 2, 2008 at 11:10 AM, Luis Abreu <lab...@gmail.com> wrote: > Hello guys.
> I guess that the problem is that we're thinking about the GetHashcode > method incorrectly. Ok, if 2 objects are equal, the hashcode must be > equal, but if two objects are different, there's nothing out there > that says that they must return a different hashcode! So, the problem > here is that we're using the hascode for equality when we shouldn't be > doing that. Even with a fancy algorythm, there's always the chance of > having 2 "different" objects returning the same hashcode.
> So, I'd really prefer to add a method that compares properties instead > of relying in hashcode. For instance, adding a method like this:
> and, of course, the Equals method oe PersistentObject to:
> public override bool Equals(object obj) { > PersistentObjectWithTypedId<IdT> compareTo = obj as > PersistentObjectWithTypedId<IdT>;
> return compareTo != null && > (HasSameNonDefaultIdAs(compareTo) || > // Since the IDs aren't the same, both of them > must be transient to > // compare business value signatures. If one is > transient and the other is > // a persisted entity, then they cannot be the same object. > (((IsTransient()) && compareTo.IsTransient()) && > DoObjectsHaveSomeBusinessSignature(compareTo))); > }
> Ok, this breaks the domainscignaturecomparable tests (only!). no doubt > about it. However. i believe that this is a good thing because I'm not > sure about these tests. For instance, the > CanCompareDomainObjectsWithOnlySomePropertiesBeingPartOfDomainSignature > looks like this:
> public void CanCompareDomainObjectsWithOnlySomePropertiesBeingPartOfDomainSignature() > { > ObjectWithOneDomainSignatureProperty object1 = new > ObjectWithOneDomainSignatureProperty(); > ObjectWithOneDomainSignatureProperty object2 = new > ObjectWithOneDomainSignatureProperty(); > Assert.That(object1, Is.Not.EqualTo(object2));
> object1.Age = 13; > object2.Age = 13; > // Name property isn't included in comparison > object1.Name = "Foo"; > object2.Name = "Bar"; > Assert.That(object1, Is.EqualTo(object2));
> Now, why do we have the first assertion? I mean, > DomainSignatureComparable does not have the concept of transitory > objects. So, I think that the 1st Assert is wrong. Here's how I expect > this class to behave:
> 1. if there isn't any property anotated with the domainsignature > attribute, then I expect it to return false (always). I assume this > because in this case equality is synonim of having the same values > applied to predefined properties. Ok, there's one case where I think > some debate is in order: what if we have two references to the same > object of a type that doesn't has any property used in the domain > signature? Ideas? Btw, it could be useful to optimize the code by > using Object.ReferenceEquals in my previous code suggestion. if it > returns true, then there's no need of going throught reflection, > right? > 2. if the class does have domain signature properties, then the > equality should be true if all those properties have the same value. > Now, if you look at the previous test, that is true: the age property > is part of the signature and since the class doesn't has the concept > of transient (delegate to the persistenobjectXXX class), then that > assert shouldn't hold. ie, two new instances will get the same value > for their ID, which means that they should be equal. Note that I'm > talking about the domainsignaturecomparable class, not anout the > persistenobjectXXX class. If the DomainSignatureComparable class had > the notion of transient object, then I would expect that assert to > hold...
> so, what do you think?
> On Thu, Oct 2, 2008 at 10:43 AM, Martin Hornagold > <Martin.Hornag...@marstangroup.com> wrote:
>> Hi guys and Billy,
>> Just did a quick hunt and found a useful article on the same problem >> documented for Java:
>> The nasty properties of XOR are: >> It treats identical pairs of components as if they were not there. >> It ignores order. A ^ B is the same a B ^ A. If order matters, you want >> some sort of checksum/digest such as Adlerian. XOR would not be suitable >> to compute the hashCode for a List which depends on the order of the >> elements as part of its identity. >> If the values to be combined are only 8 bits wide, there will be >> effectively only 8 bits in the xored result. In contrast, multiplying by >> a prime and adding would scramble the entire 32 bits of the result, >> giving a much broader range of possible values, hence greater chance >> that each hashcode will unique to a single Object. In other words, it >> tends to expand the range of the digest into the widest possible band >> (32 bits).
Luis, I agree with both of your statements below regarding the DomainSignatureComparable behavior. I think that the Object.ReferenceEquals handles the situation where we have two references to the same object of a type that doesn't have any property used in the domain. My only change to the code that you provided would be to possibly make the hash code a little more unique by changing the GetDomainObjectSignature method to the following:
protected virtual int GetDomainObjectSignature() { var domainObjectSignature = 0; var strValues = new StringBuilder();
foreach (var property in GetType().GetProperties()) { if (!IsPartOfDomainSignature(property)) { continue; } var value = property.GetValue(this, null);
if (value != null) { strValues.Append(value.ToString()); } }
// If no properties were flagged as being part of the domain signature of the object, // then simply return the hashcode of the base object as the domain signature. This // behaves as you would normally expect Equals to behave when comparing two objects. return strValues.ToString().GetHashCode == 0 ? base.GetHashCode() : domainObjectSignature; }
By appending the string values to a single hash code it seems to return a unique code in the test case that I had previously had problems with. I still agree that we should not rely on the hash code to determine property equality though.
[mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu Sent: Thursday, October 02, 2008 5:10 AM To: sharp-architecture@googlegroups.com Subject: Re: Equals and Hashcode question in new release?
Hello guys.
I guess that the problem is that we're thinking about the GetHashcode method incorrectly. Ok, if 2 objects are equal, the hashcode must be equal, but if two objects are different, there's nothing out there that says that they must return a different hashcode! So, the problem here is that we're using the hascode for equality when we shouldn't be doing that. Even with a fancy algorythm, there's always the chance of having 2 "different" objects returning the same hashcode.
So, I'd really prefer to add a method that compares properties instead of relying in hashcode. For instance, adding a method like this:
and, of course, the Equals method oe PersistentObject to:
public override bool Equals(object obj) { PersistentObjectWithTypedId<IdT> compareTo = obj as PersistentObjectWithTypedId<IdT>;
return compareTo != null && (HasSameNonDefaultIdAs(compareTo) || // Since the IDs aren't the same, both of them must be transient to // compare business value signatures. If one is transient and the other is // a persisted entity, then they cannot be the same object. (((IsTransient()) && compareTo.IsTransient()) && DoObjectsHaveSomeBusinessSignature(compareTo))); }
Ok, this breaks the domainscignaturecomparable tests (only!). no doubt about it. However. i believe that this is a good thing because I'm not sure about these tests. For instance, the CanCompareDomainObjectsWithOnlySomePropertiesBeingPartOfDomainSignature looks like this:
public void CanCompareDomainObjectsWithOnlySomePropertiesBeingPartOfDomainSignature() { ObjectWithOneDomainSignatureProperty object1 = new ObjectWithOneDomainSignatureProperty(); ObjectWithOneDomainSignatureProperty object2 = new ObjectWithOneDomainSignatureProperty(); Assert.That(object1, Is.Not.EqualTo(object2));
object1.Age = 13; object2.Age = 13; // Name property isn't included in comparison object1.Name = "Foo"; object2.Name = "Bar"; Assert.That(object1, Is.EqualTo(object2));
Now, why do we have the first assertion? I mean, DomainSignatureComparable does not have the concept of transitory objects. So, I think that the 1st Assert is wrong. Here's how I expect this class to behave:
1. if there isn't any property anotated with the domainsignature attribute, then I expect it to return false (always). I assume this because in this case equality is synonim of having the same values applied to predefined properties. Ok, there's one case where I think some debate is in order: what if we have two references to the same object of a type that doesn't has any property used in the domain signature? Ideas? Btw, it could be useful to optimize the code by using Object.ReferenceEquals in my previous code suggestion. if it returns true, then there's no need of going throught reflection, right? 2. if the class does have domain signature properties, then the equality should be true if all those properties have the same value. Now, if you look at the previous test, that is true: the age property is part of the signature and since the class doesn't has the concept of transient (delegate to the persistenobjectXXX class), then that assert shouldn't hold. ie, two new instances will get the same value for their ID, which means that they should be equal. Note that I'm talking about the domainsignaturecomparable class, not anout the persistenobjectXXX class. If the DomainSignatureComparable class had the notion of transient object, then I would expect that assert to hold...
so, what do you think?
On Thu, Oct 2, 2008 at 10:43 AM, Martin Hornagold <Martin.Hornag...@marstangroup.com> wrote:
> Hi guys and Billy,
> Just did a quick hunt and found a useful article on the same problem > documented for Java:
> The nasty properties of XOR are: > It treats identical pairs of components as if they were not there. > It ignores order. A ^ B is the same a B ^ A. If order matters, you want > some sort of checksum/digest such as Adlerian. XOR would not be suitable > to compute the hashCode for a List which depends on the order of the > elements as part of its identity. > If the values to be combined are only 8 bits wide, there will be > effectively only 8 bits in the xored result. In contrast, multiplying by > a prime and adding would scramble the entire 32 bits of the result, > giving a much broader range of possible values, hence greater chance > that each hashcode will unique to a single Object. In other words, it > tends to expand the range of the digest into the widest possible band > (32 bits).
> There are some examples of implementation.
> Hope it helps
> Martin
> -----Original Message----- > From: sharp-architecture@googlegroups.com > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > Sent: 02 October 2008 10:27 > To: sharp-architecture@googlegroups.com > Subject: Re: Equals and Hashcode question in new release?
> incredible...I've just run some powershell tests and yes, you're > correct. Interestingly, each string has its own integer value but when > youo combine them with ^operator you get the same result...
> so, we do need some way to corretly implement hascode...anyone good with > math?
> On Wed, Oct 1, 2008 at 11:11 PM, Brian Nicoloff <nicol...@sbcglobal.net> > wrote:
>> Yes, that was my assumption of the way that the hash code worked as > well. >> But, running the test through the debugger brings up the same HashCode > in >> the GetDomainObjectSignature() method for the following objects where >> FirstName and LastName are the combined DomainSignature for the class.
>> -----Original Message----- >> From: sharp-architecture@googlegroups.com >> [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu >> Sent: Wednesday, October 01, 2008 4:51 PM >> To: sharp-architecture@googlegroups.com >> Subject: RE: Equals and Hashcode question in new release?
>> Hum...that is interesting...I mean, in my case, it was obvious I'd get > the >> same hash because I?ve just exchanged the properties' values, but in > yours >> you had different values (ie, you f1/l1 and then f2/l2 - or something > along >> these lines). I expected that the hashcode for these would always be >> different, but again, I might be wrong.
> -----Original Message----- > From: sharp-architecture@googlegroups.com [mailto:sharp- > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > Sent: quinta-feira, 2 de Outubro de 2008 16:58 > To: sharp-architecture@googlegroups.com > Subject: RE: Equals and Hashcode question in new release?
> Luis, > I agree with both of your statements below regarding the > DomainSignatureComparable behavior. I think that the > Object.ReferenceEquals > handles the situation where we have two references to the same object > of a > type that doesn't have any property used in the domain. My only change > to > the code that you provided would be to possibly make the hash code a > little > more unique by changing the GetDomainObjectSignature method to the > following:
> protected virtual int GetDomainObjectSignature() > { > var domainObjectSignature = 0; > var strValues = new StringBuilder();
> foreach (var property in GetType().GetProperties()) > { > if (!IsPartOfDomainSignature(property)) > { > continue; > } > var value = property.GetValue(this, null);
> // If no properties were flagged as being part of the domain > signature > of the object, > // then simply return the hashcode of the base object as the domain > signature. This > // behaves as you would normally expect Equals to behave when > comparing > two objects. > return strValues.ToString().GetHashCode == 0 ? base.GetHashCode() : > domainObjectSignature; > }
> By appending the string values to a single hash code it seems to return > a > unique code in the test case that I had previously had problems with. > I > still agree that we should not rely on the hash code to determine > property > equality though.
> Brian
> -----Original Message----- > From: sharp-architecture@googlegroups.com > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > Sent: Thursday, October 02, 2008 5:10 AM > To: sharp-architecture@googlegroups.com > Subject: Re: Equals and Hashcode question in new release?
> Hello guys.
> I guess that the problem is that we're thinking about the GetHashcode > method incorrectly. Ok, if 2 objects are equal, the hashcode must be > equal, but if two objects are different, there's nothing out there > that says that they must return a different hashcode! So, the problem > here is that we're using the hascode for equality when we shouldn't be > doing that. Even with a fancy algorythm, there's always the chance of > having 2 "different" objects returning the same hashcode.
> So, I'd really prefer to add a method that compares properties instead > of relying in hashcode. For instance, adding a method like this:
> and, of course, the Equals method oe PersistentObject to:
> public override bool Equals(object obj) { > PersistentObjectWithTypedId<IdT> compareTo = obj as > PersistentObjectWithTypedId<IdT>;
> return compareTo != null && > (HasSameNonDefaultIdAs(compareTo) || > // Since the IDs aren't the same, both of them > must be transient to > // compare business value signatures. If one is > transient and the other is > // a persisted entity, then they cannot be the same > object. > (((IsTransient()) && compareTo.IsTransient()) && > DoObjectsHaveSomeBusinessSignature(compareTo))); > }
> Ok, this breaks the domainscignaturecomparable tests (only!). no doubt > about it. However. i believe that this is a good thing because I'm not > sure about these tests. For instance, the > CanCompareDomainObjectsWithOnlySomePropertiesBeingPartOfDomainSignature > looks like this:
> public void > CanCompareDomainObjectsWithOnlySomePropertiesBeingPartOfDomainSignature > () > { > ObjectWithOneDomainSignatureProperty object1 = new > ObjectWithOneDomainSignatureProperty(); > ObjectWithOneDomainSignatureProperty object2 = new > ObjectWithOneDomainSignatureProperty(); > Assert.That(object1, Is.Not.EqualTo(object2));
> object1.Age = 13; > object2.Age = 13; > // Name property isn't included in comparison > object1.Name = "Foo"; > object2.Name = "Bar"; > Assert.That(object1, Is.EqualTo(object2));
> Now, why do we have the first assertion? I mean, > DomainSignatureComparable does not have the concept of transitory > objects. So, I think that the 1st Assert is wrong. Here's how I expect > this class to behave:
> 1. if there isn't any property anotated with the domainsignature > attribute, then I expect it to return false (always). I assume this > because in this case equality is synonim of having the same values > applied to predefined properties. Ok, there's one case where I think > some debate is in order: what if we have two references to the same > object of a type that doesn't has any property used in the domain > signature? Ideas? Btw, it could be useful to optimize the code by > using Object.ReferenceEquals in my previous code suggestion. if it > returns true, then there's no need of going throught reflection, > right? > 2. if the class does have domain signature properties, then the > equality should be true if all those properties have the same value. > Now, if you look at the previous test, that is true: the age property > is part of the signature and since the class doesn't has the concept > of transient (delegate to the persistenobjectXXX class), then that > assert shouldn't hold. ie, two new instances will get the same value > for their ID, which means that they should be equal. Note that I'm > talking about the domainsignaturecomparable class, not anout the > persistenobjectXXX class. If the DomainSignatureComparable class had > the notion of transient object, then I would expect that assert to > hold...
> so, what do you think?
> On Thu, Oct 2, 2008 at 10:43 AM, Martin Hornagold > <Martin.Hornag...@marstangroup.com> wrote:
> > Hi guys and Billy,
> > Just did a quick hunt and found a useful article on the same problem > > documented for Java:
> > The nasty properties of XOR are: > > It treats identical pairs of components as if they were not there. > > It ignores order. A ^ B is the same a B ^ A. If order matters, you > want > > some sort of checksum/digest such as Adlerian. XOR would not be > suitable > > to compute the hashCode for a List which depends on the order of the > > elements as part of its identity. > > If the values to be combined are only 8 bits wide, there will be > > effectively only 8 bits in the xored result. In contrast, multiplying > by > > a prime and adding would scramble the entire 32 bits of the result, > > giving a much broader range of possible values, hence greater chance > > that each hashcode will unique to a single Object. In other words, it > > tends to expand the range of the digest into the widest possible band > > (32 bits).
> > There are some examples of implementation.
> > Hope it helps
> > Martin
> > -----Original Message----- > > From: sharp-architecture@googlegroups.com > > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > > Sent: 02 October 2008 10:27 > > To: sharp-architecture@googlegroups.com > > Subject: Re: Equals and Hashcode question in new release?
> > incredible...I've just run some powershell tests and yes, you're > > correct. Interestingly, each string has its own integer value but > when > > youo combine them with ^operator you get the same result...
> > so, we do need some way to corretly implement hascode...anyone good > with > > math?
> > On Wed, Oct 1, 2008 at 11:11 PM, Brian Nicoloff > <nicol...@sbcglobal.net> > > wrote:
> >> Yes, that was my assumption of the way that the hash code worked as > > well. > >> But, running the test through the debugger brings up the same > HashCode > > in > >> the GetDomainObjectSignature() method for the following objects > where > >> FirstName and LastName are the combined DomainSignature for the > class.
[mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu Sent: Thursday, October 02, 2008 2:56 PM To: sharp-architecture@googlegroups.com Subject: RE: Equals and Hashcode question in new release?
Hum...well, calculating a hashcode is...you know, hard:)
Most of the implementations I've seen are really happy delegating to its inner properties, so I'd leave it like that...
Anyways, we must wait for Billy to see what he thinks about the ideas we've presented here.
-- Luis Abreu
> -----Original Message----- > From: sharp-architecture@googlegroups.com [mailto:sharp- > architecture@googlegroups.com] On Behalf Of Brian Nicoloff > Sent: quinta-feira, 2 de Outubro de 2008 16:58 > To: sharp-architecture@googlegroups.com > Subject: RE: Equals and Hashcode question in new release?
> Luis, > I agree with both of your statements below regarding the > DomainSignatureComparable behavior. I think that the > Object.ReferenceEquals > handles the situation where we have two references to the same object > of a > type that doesn't have any property used in the domain. My only change > to > the code that you provided would be to possibly make the hash code a > little > more unique by changing the GetDomainObjectSignature method to the > following:
> protected virtual int GetDomainObjectSignature() > { > var domainObjectSignature = 0; > var strValues = new StringBuilder();
> foreach (var property in GetType().GetProperties()) > { > if (!IsPartOfDomainSignature(property)) > { > continue; > } > var value = property.GetValue(this, null);
> // If no properties were flagged as being part of the domain > signature > of the object, > // then simply return the hashcode of the base object as the domain > signature. This > // behaves as you would normally expect Equals to behave when > comparing > two objects. > return strValues.ToString().GetHashCode == 0 ? base.GetHashCode() : > domainObjectSignature; > }
> By appending the string values to a single hash code it seems to return > a > unique code in the test case that I had previously had problems with. > I > still agree that we should not rely on the hash code to determine > property > equality though.
> Brian
> -----Original Message----- > From: sharp-architecture@googlegroups.com > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > Sent: Thursday, October 02, 2008 5:10 AM > To: sharp-architecture@googlegroups.com > Subject: Re: Equals and Hashcode question in new release?
> Hello guys.
> I guess that the problem is that we're thinking about the GetHashcode > method incorrectly. Ok, if 2 objects are equal, the hashcode must be > equal, but if two objects are different, there's nothing out there > that says that they must return a different hashcode! So, the problem > here is that we're using the hascode for equality when we shouldn't be > doing that. Even with a fancy algorythm, there's always the chance of > having 2 "different" objects returning the same hashcode.
> So, I'd really prefer to add a method that compares properties instead > of relying in hashcode. For instance, adding a method like this:
> and, of course, the Equals method oe PersistentObject to:
> public override bool Equals(object obj) { > PersistentObjectWithTypedId<IdT> compareTo = obj as > PersistentObjectWithTypedId<IdT>;
> return compareTo != null && > (HasSameNonDefaultIdAs(compareTo) || > // Since the IDs aren't the same, both of them > must be transient to > // compare business value signatures. If one is > transient and the other is > // a persisted entity, then they cannot be the same > object. > (((IsTransient()) && compareTo.IsTransient()) && > DoObjectsHaveSomeBusinessSignature(compareTo))); > }
> Ok, this breaks the domainscignaturecomparable tests (only!). no doubt > about it. However. i believe that this is a good thing because I'm not > sure about these tests. For instance, the > CanCompareDomainObjectsWithOnlySomePropertiesBeingPartOfDomainSignature > looks like this:
> public void > CanCompareDomainObjectsWithOnlySomePropertiesBeingPartOfDomainSignature > () > { > ObjectWithOneDomainSignatureProperty object1 = new > ObjectWithOneDomainSignatureProperty(); > ObjectWithOneDomainSignatureProperty object2 = new > ObjectWithOneDomainSignatureProperty(); > Assert.That(object1, Is.Not.EqualTo(object2));
> object1.Age = 13; > object2.Age = 13; > // Name property isn't included in comparison > object1.Name = "Foo"; > object2.Name = "Bar"; > Assert.That(object1, Is.EqualTo(object2));
> Now, why do we have the first assertion? I mean, > DomainSignatureComparable does not have the concept of transitory > objects. So, I think that the 1st Assert is wrong. Here's how I expect > this class to behave:
> 1. if there isn't any property anotated with the domainsignature > attribute, then I expect it to return false (always). I assume this > because in this case equality is synonim of having the same values > applied to predefined properties. Ok, there's one case where I think > some debate is in order: what if we have two references to the same > object of a type that doesn't has any property used in the domain > signature? Ideas? Btw, it could be useful to optimize the code by > using Object.ReferenceEquals in my previous code suggestion. if it > returns true, then there's no need of going throught reflection, > right? > 2. if the class does have domain signature properties, then the > equality should be true if all those properties have the same value. > Now, if you look at the previous test, that is true: the age property > is part of the signature and since the class doesn't has the concept > of transient (delegate to the persistenobjectXXX class), then that > assert shouldn't hold. ie, two new instances will get the same value > for their ID, which means that they should be equal. Note that I'm > talking about the domainsignaturecomparable class, not anout the > persistenobjectXXX class. If the DomainSignatureComparable class had > the notion of transient object, then I would expect that assert to > hold...
> so, what do you think?
> On Thu, Oct 2, 2008 at 10:43 AM, Martin Hornagold > <Martin.Hornag...@marstangroup.com> wrote:
> > Hi guys and Billy,
> > Just did a quick hunt and found a useful article on the same problem > > documented for Java:
> > The nasty properties of XOR are: > > It treats identical pairs of components as if they were not there. > > It ignores order. A ^ B is the same a B ^ A. If order matters, you > want > > some sort of checksum/digest such as Adlerian. XOR would not be > suitable > > to compute the hashCode for a List which depends on the order of the > > elements as part of its identity. > > If the values to be combined are only 8 bits wide, there will be > > effectively only 8 bits in the xored result. In contrast, multiplying > by > > a prime and adding would scramble the entire 32 bits of the result, > > giving a much broader range of possible values, hence greater chance > > that each hashcode will unique to a single Object. In other words, it > > tends to expand the range of the digest into the widest possible band > > (32 bits).
> > There are some examples of implementation.
> > Hope it helps
> > Martin
> > -----Original Message----- > > From: sharp-architecture@googlegroups.com > > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Luis Abreu > > Sent: 02 October 2008 10:27 > > To: sharp-architecture@googlegroups.com > > Subject: Re: Equals and Hashcode question in new release?
> > incredible...I've just run some powershell tests and yes, you're > > correct. Interestingly, each string has its own integer value but > when > > youo combine them with ^operator you get the same result...
> > so, we do need some way to corretly implement hascode...anyone good > with > > math?
> > On Wed, Oct 1, 2008 at 11:11 PM, Brian Nicoloff > <nicol...@sbcglobal.net> > > wrote:
> >> Yes, that was my assumption of the way that the hash code worked as
On Wed, Oct 1, 2008 at 7:08 AM, Billy <googlegro...@emccafferty.com> wrote:
> After a long delay, I finally have 0.8 available for download which > includes the official release of S#arp Architecture using MVC Preview > 5, NHibernate 2.0 and Ninject 1.0.
> Here is a summary of some of the more significant changes (some > breaking changes) in this release: > * Documentation has been completely updated and much new content has > been added > * ProjectBase has been renamed to SharpArch > * Ninject is now the official mechanism for performing dependency > injection > * The Equals/GetHashCode has been overhauled to be much faster; > additionally, it no longer sees a transient and persistent object as > being the same if their domain signatures are the same > * The basic Equals/GetHashCode logic has been pulled up into the > abstract class SharpArch.Core/DomainSignatureComparable.cs; this may > be used as a base class for non-persistent domain classes to provide > consistent Equals/GetHashCode behavior, e.g. an Address object mapped > as a component of an Employee > * Unit tests have been added to the SharpArch solution; it's not > comprehensive yet, but it's a start
> I feel that this is the first major release with a codebase which will > no longer be changing much. Most of the changes which will be coming > in future releases will be upgrades to third party components such as > ASP.NET MVC and NHibernate, inclusion of support for new areas of > functionality such as WCF, and more sample code. So it is my > intention that future releases will have very few breaking changes.
No! In fact, the changes that I just checked in (which I'll be making
0.8.1) include most of the patch which you've provided (and probably
thought that I did not notice)...so thank you Simone for the
contribution!! Additionally, I'd like to sincerely thank Brian
Nicoloff (especially for the comprehensive unit tests), Luis Abreu,
and Martin Hornagold for this discussion which exposed a serious flaw
in the existing logic and provided terrific discussion for the
applicability of Equals and GetHashCode, and the logic therein. The
fact of the matter is, this architecture, and current release, is a
true reflection of everyone who has participated within these
discussions. I only wish to keep the check in/out of the core code
base between now and 1.0 to myself and Frank Laub, who has been
instrumental in the formalization of this architecture, for the sole
motivation that I wish to consider the feedback from all developers
and incorporate the guidance which is most in line with my own
(arguably selfish) goals for where I want this architecture to be and
how I want it to be used. My aspiration is that S#arp Architecture
will become the "Ruby on Rails" foundation for ASP.NET MVC; I feel
that we will get it there with all of your input and assistance.
The most recent check-in (which will be part of 0.8.1) includes the
following assumptions with respect to Equals and GetHashCode:
* Equals and GetHashCode should behave identically (this is up for
argument from a theoretical standpoint but an assumption for #arch).
Similar to the guidance provided within
http://www.hibernate.org/hib_docs/nhibernate/html/persistent-classes.... , the code with #arch leverages the GetHashCode method to enable
checks for equality; #arch is just a bit more explicit about the
assumed overlap;
* If two objects inherit from DomainSignatureComparable, and are
compared, then it is assumed that the comparison between the two is
solely dependent on the properties marked with the attribute
[DomainSignature]. If no properties are decorated with the
DomainSignature attribute, then the comparison between the two objects
is treated as .NET natively compares object equality: by memory
reference with the ReferenceEquals method;
* Two DomainSignatureComparable objects which point to the same memory
location (i.e., are the same object in memory) are always equal;
* Two PersistentObject/PersistentObjectWithTypedId objects which have
the same ID are always equal;
* If two PersistentObject are compared and one of them is transient
while the other is persistent, they will always be different from a
standpoint from equality;
* Any PersistentObject properties which are not decorated with the
DomainSignature attribute will not be included in the comparison of
two PersistentObject object; consequently, ONLY the properties
decorated with the DomainSinature attribute will have an impact on
comparison.
As always, your continued feedback is most appreciated.
Billy
On Oct 4, 4:40 pm, "Simone Busoli" <simone.bus...@gmail.com> wrote:
> Billy, is the project going to be a one man show forever? Just to know if I,
> or anyone, should bother discussing changes, fixes or improvements.
> On Wed, Oct 1, 2008 at 7:08 AM, Billy <googlegro...@emccafferty.com> wrote:
> > After a long delay, I finally have 0.8 available for download which
> > includes the official release of S#arp Architecture using MVC Preview
> > 5, NHibernate 2.0 and Ninject 1.0.
> > Here is a summary of some of the more significant changes (some
> > breaking changes) in this release:
> > * Documentation has been completely updated and much new content has
> > been added
> > * ProjectBase has been renamed to SharpArch
> > * Ninject is now the official mechanism for performing dependency
> > injection
> > * The Equals/GetHashCode has been overhauled to be much faster;
> > additionally, it no longer sees a transient and persistent object as
> > being the same if their domain signatures are the same
> > * The basic Equals/GetHashCode logic has been pulled up into the
> > abstract class SharpArch.Core/DomainSignatureComparable.cs; this may
> > be used as a base class for non-persistent domain classes to provide
> > consistent Equals/GetHashCode behavior, e.g. an Address object mapped
> > as a component of an Employee
> > * Unit tests have been added to the SharpArch solution; it's not
> > comprehensive yet, but it's a start
> > I feel that this is the first major release with a codebase which will
> > no longer be changing much. Most of the changes which will be coming
> > in future releases will be upgrades to third party components such as
> > ASP.NET MVC and NHibernate, inclusion of support for new areas of
> > functionality such as WCF, and more sample code. So it is my
> > intention that future releases will have very few breaking changes.
Just one question (probably didn't get this right):
> * Two PersistentObject/PersistentObjectWithTypedId objects which have > the same ID are always equal;
So, are you using the db key for checking equality between objects? Are we dismissing the attributes annotated with the DomainSignatureAttribute from this comparison? If so, is this wise?
On Sun, Oct 5, 2008 at 7:18 PM, Luis Abreu <lab...@gmail.com> wrote:
> Hello guys,
> Just one question (probably didn't get this right):
> > * Two PersistentObject/PersistentObjectWithTypedId objects which have > > the same ID are always equal;
> So, are you using the db key for checking equality between objects? Are we > dismissing the attributes annotated with the DomainSignatureAttribute from > this comparison? If so, is this wise?
Probably, but the question is: does it work in all the scenarios?
-- Luis Abreu
From: sharp-architecture@googlegroups.com [mailto:sharp-architecture@googlegroups.com] On Behalf Of Simone Busoli Sent: domingo, 5 de Outubro de 2008 18:52 To: sharp-architecture@googlegroups.com Subject: Re: Version 0.8.0 with MVC Preview 5, NH 2.0 and Ninject 1.0 now available!
If two objects are persistent, doesn't it make sense to consider them equal if they have the same ID? The ID is not necessarily the ID in the DB.
On Sun, Oct 5, 2008 at 7:18 PM, Luis Abreu <lab...@gmail.com> wrote:
Hello guys,
Just one question (probably didn't get this right):
> * Two PersistentObject/PersistentObjectWithTypedId objects which have > the same ID are always equal;
So, are you using the db key for checking equality between objects? Are we dismissing the attributes annotated with the DomainSignatureAttribute from this comparison? If so, is this wise?
Luis
No virus found in this incoming message. Checked by AVG - http://www.avg.com Version: 8.0.173 / Virus Database: 270.7.5/1703 - Release Date: 05-10-2008 09:20
Assuming equal ID (and type) implies object equality is the approach
I've been using for a few years and I haven't run into an outside case
yet; not that that means that it's inappropriate in some situations,
but I have yet to run into them. My thoughts on this is that if you
legally change your name from Luis to George, that you're still the
same person that you were before but with a different property value.
Your ID in this instance would be an assigned ID being your social
security number (or possibly some auto-generated one from the DB).
Billy
On Oct 5, 1:12 pm, "Luis Abreu" <lab...@gmail.com> wrote:
> Probably, but the question is: does it work in all the scenarios?
> --
> Luis Abreu
> From: sharp-architecture@googlegroups.com
> [mailto:sharp-architecture@googlegroups.com] On Behalf Of Simone Busoli
> Sent: domingo, 5 de Outubro de 2008 18:52
> To: sharp-architecture@googlegroups.com
> Subject: Re: Version 0.8.0 with MVC Preview 5, NH 2.0 and Ninject 1.0 now
> available!
> If two objects are persistent, doesn't it make sense to consider them equal
> if they have the same ID? The ID is not necessarily the ID in the DB.
> On Sun, Oct 5, 2008 at 7:18 PM, Luis Abreu <lab...@gmail.com> wrote:
> Hello guys,
> Just one question (probably didn't get this right):
> > * Two PersistentObject/PersistentObjectWithTypedId objects which have
> > the same ID are always equal;
> So, are you using the db key for checking equality between objects? Are we
> dismissing the attributes annotated with the DomainSignatureAttribute from
> this comparison? If so, is this wise?
> Luis
> No virus found in this incoming message.
> Checked by AVG -http://www.avg.com > Version: 8.0.173 / Virus Database: 270.7.5/1703 - Release Date: 05-10-2008
> 09:20
This is definitely the way to go with persistent objects, at least according to DDD, where objects with an identity are called entities. Their identity is not regulated by the equality of their attributes (these are called value objects), but by a higher level concept, according to the domain in which your objects live.
On Mon, Oct 6, 2008 at 1:11 AM, Billy <googlegro...@emccafferty.com> wrote:
> Assuming equal ID (and type) implies object equality is the approach > I've been using for a few years and I haven't run into an outside case > yet; not that that means that it's inappropriate in some situations, > but I have yet to run into them. My thoughts on this is that if you > legally change your name from Luis to George, that you're still the > same person that you were before but with a different property value. > Your ID in this instance would be an assigned ID being your social > security number (or possibly some auto-generated one from the DB).
> Billy
> On Oct 5, 1:12 pm, "Luis Abreu" <lab...@gmail.com> wrote: > > Probably, but the question is: does it work in all the scenarios?
> > -- > > Luis Abreu
> > From: sharp-architecture@googlegroups.com > > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Simone Busoli > > Sent: domingo, 5 de Outubro de 2008 18:52 > > To: sharp-architecture@googlegroups.com > > Subject: Re: Version 0.8.0 with MVC Preview 5, NH 2.0 and Ninject 1.0 now > > available!
> > If two objects are persistent, doesn't it make sense to consider them > equal > > if they have the same ID? The ID is not necessarily the ID in the DB.
> > On Sun, Oct 5, 2008 at 7:18 PM, Luis Abreu <lab...@gmail.com> wrote:
> > Hello guys,
> > Just one question (probably didn't get this right):
> > > * Two PersistentObject/PersistentObjectWithTypedId objects which have > > > the same ID are always equal;
> > So, are you using the db key for checking equality between objects? Are > we > > dismissing the attributes annotated with the DomainSignatureAttribute > from > > this comparison? If so, is this wise?
> > Luis
> > No virus found in this incoming message. > > Checked by AVG -http://www.avg.com > > Version: 8.0.173 / Virus Database: 270.7.5/1703 - Release Date: > 05-10-2008 > > 09:20
regarding the name change, that's where the domain business signature enters. You wouldn't promote Name to a business signature, right?
I'll have to think a little more about that to see if I agree. I mean, it makes sense, but you'll also need to garantee that nobody changes the value of the ID after its set....need to think a little more about it....
On Mon, Oct 6, 2008 at 12:20 AM, Simone Busoli <simone.bus...@gmail.com> wrote: > This is definitely the way to go with persistent objects, at least according > to DDD, where objects with an identity are called entities. Their identity > is not regulated by the equality of their attributes (these are called value > objects), but by a higher level concept, according to the domain in which > your objects live.
> On Mon, Oct 6, 2008 at 1:11 AM, Billy <googlegro...@emccafferty.com> wrote:
>> Assuming equal ID (and type) implies object equality is the approach >> I've been using for a few years and I haven't run into an outside case >> yet; not that that means that it's inappropriate in some situations, >> but I have yet to run into them. My thoughts on this is that if you >> legally change your name from Luis to George, that you're still the >> same person that you were before but with a different property value. >> Your ID in this instance would be an assigned ID being your social >> security number (or possibly some auto-generated one from the DB).
>> Billy
>> On Oct 5, 1:12 pm, "Luis Abreu" <lab...@gmail.com> wrote: >> > Probably, but the question is: does it work in all the scenarios?
>> > -- >> > Luis Abreu
>> > From: sharp-architecture@googlegroups.com >> > [mailto:sharp-architecture@googlegroups.com] On Behalf Of Simone Busoli >> > Sent: domingo, 5 de Outubro de 2008 18:52 >> > To: sharp-architecture@googlegroups.com >> > Subject: Re: Version 0.8.0 with MVC Preview 5, NH 2.0 and Ninject 1.0 >> > now >> > available!
>> > If two objects are persistent, doesn't it make sense to consider them >> > equal >> > if they have the same ID? The ID is not necessarily the ID in the DB.
>> > On Sun, Oct 5, 2008 at 7:18 PM, Luis Abreu <lab...@gmail.com> wrote:
>> > Hello guys,
>> > Just one question (probably didn't get this right):
>> > > * Two PersistentObject/PersistentObjectWithTypedId objects which have >> > > the same ID are always equal;
>> > So, are you using the db key for checking equality between objects? Are >> > we >> > dismissing the attributes annotated with the DomainSignatureAttribute >> > from >> > this comparison? If so, is this wise?
>> > Luis
>> > No virus found in this incoming message. >> > Checked by AVG -http://www.avg.com >> > Version: 8.0.173 / Virus Database: 270.7.5/1703 - Release Date: >> > 05-10-2008 >> > 09:20