In NHibernate 3.0 Cookbook, there is a sample implementation for a base Entity type. The equals is implemented like this:
public abstract class Entity<TId>
{
public virtual TId Id { get; protected set; }
public override bool Equals(object obj)
{
return Equals(obj as Entity<TId>);
}
private static bool IsTransient(Entity<TId> obj)
{
return obj != null && Equals(obj.Id, default(TId));
}
private Type GetUnproxiedType()
{
return GetType();
}
public virtual bool Equals(Entity<TId> other)
{
if (other == null) return false;
if (ReferenceEquals(this, other)) return true;
if (!IsTransient(this) && !IsTransient(this) && Equals(Id, other.Id))
{
var otherType = other.GetUnproxiedType();
var thisType = GetUnproxiedType();
return thisType.IsAssignableFrom(otherType) ||
otherType.IsAssignableFrom(thisType);
}
return false;
}
}
The reason for the GetUnproxiedType() method is this: There is an abstract base class Product, a concrete class Book which inherits from Product and a dynamic proxy class ProductProxy used by NHibernate for lazy loading. If a ProductProxy representing a Book and a concrete Book have the same Ids, they should be treated as equal. However I don't really see why calling GetType() on a ProductProxy instance should return Product in this case, and how it helps. Any ideas?
I actually went ahead and wrote to the author of the book about this code. It turns out this is due to how the proxy wrapping works. Here is his response:
"If you don't understand how the proxy frameworks work, the idea can seem magical.
When NHibernate returns a proxy for the purposes of lazy loading, it returns a proxy instance inherited from the actual type. There are a few members we can access without forcing a load from the database. Among these are proxy's Id property or field, GetType(), and in some circumstances Equals() and GetHashCode(). Accessing any other member will force a load from the database.
When that happens, the proxy creates an internal instance. So, for example, a lazy loaded instance of Customer (CustomerProxy102987098721340978), when loaded, will internally create a new Customer instance with all of the data from the database. The proxy then does something like this:
public overrides string Name
{
get {
return _loadedInstance.Name;
}
set { _loadedInstance.Name = value; }
}
Incidentally, it's this overriding that requires everything to be virtual on entities that allow lazy loaded.
So, all calls to the Name property on the proxy are relayed to the internal Customer instance that has the actual data.
GetUnproxiedType() takes advantage of this. A simple call to GetType() on the proxy will return typeof(CustomerProxy02139487509812340). A call to GetUnproxiedType() will be relayed to the internal customer instance, and the internal customer instance will return typeof(Customer)."
With current (v5.x) NHibernate proxy factories (static or dynamic, static being available since v5.1), this pattern is actually broken. The v5 built-in proxy factories do not intercept private methods.
And I think that was already the case for v4 ones.
For this pattern to work with current built-in proxy factories, GetUnproxiedType should be virtual (so not private by the way, but protected).
Otherwise, use NHibernateUtil.GetClass, which is meant for this and does not rely on brittle tricks. Its documentation warns it will initialize the proxy by side effect, but anyway the GetUnproxiedType trick must do the same for working.
Of course using NHibernateUtil.GetClass means having a direct dependency to NHibernate in a domain model base class. But depending on an implementation trick specific to an external (from the domain viewpoint) library implementation is no better in my opinion.
Moreover, some changes may cause the GetUnproxiedType trick to be even more broken in the future, like some ideas for reducing the number of cases causing a proxy to get initialized when it could be avoided. (See here by example.)
If you really want a GetUnproxiedType method not depending on a direct NHibernate reference, I think the only theoretically "safe" solution is to have it abstract and overridden in each concrete entity class for yielding typeof(YourEntityClass). But in practice, it would be cumbersome and error-prone (bad copy-paste for creating a new entity, forgetting to change that method...), while the abstract part won't help in case some concrete entity classes are further specialized through inheritance.
Another trick could be, from the type obtained by GetType, to check to which assembly it belongs (the proxy type will not belong to one of your assemblies), for searching the first type in the hierarchy belonging to your domain model assembly(ies).
Note that if the proxy is a proxy of a base class, not of a concrete class, and your helper method is set as private, it will yield the base class type, without initializing the proxy. Performance-wise, this is better. While a virtual GetUnproxiedType simply returning GetType would return the concrete class type with current proxy factories, but it would also initialize the proxy.
We use NH 2 and this example did not work for us. (It FAILED to unproxy the type and left proxy type, see below).
It said that 2 entities with the same id are not equal, when one of them is proxy(of COrganization) and other is not(DOrganization).
When we had a hierarchy:
class Organization
class AOrganization : Organization
class COrganization : Organization
{
public virtual COrganization GetConcrete()
{
return null;
}
}
class DOrganization : COrganization
{
public virtual COrganization GetConcrete()
{
return this;
}
}
AOrganization aOrganization;
COrganization cOrganization;
contract = new CContract(aOrganization, cOrganization as COrganization); //(COrganization)(cOrganization.GetConcrete()),
So CContract has a field of type COrganization. With a setter
public class Contract: Entity <short>
{
public virtual COrganization COrganization
{
get { return cOrganization; }
protected internal set
{
if (cOrganization != null && value != cOrganization) // != calls ==, which calls Equals, which calls GetUnproxiedType()
throw new Exception("Changing organization is not allowed.");
}
cOrganization = value;
}
}
private COrganization cOrganization;
}
We constructed new Contract, its constructor set the COrganization field pointing to some organization. Then we called UnitOfWork.Commit, NH tried to set COrganization field again (with the same id), GetUnproxiedType worked incorrectly, new and old values were recognized as non-equal, and exception was thrown...
Here is the place where error showed up:
var otherType = other.GetUnproxiedType();
var thisType = GetUnproxiedType();
return thisType.IsAssignableFrom(otherType) ||
otherType.IsAssignableFrom(thisType);
In debugger: otherType == COrganizationProxy - GetUnproxiedType failed...
thisType == DOrganization
COrganizationProxy and DOrganization both inherit COrganization.
So they are not IsAssignableFrom for each other...
Why does this example work for you?
Maybe because we have NH 2.0 or 2.1?
Or because of simple "cOrganization as COrganization" instead of "(COrganization)(cOrganization.GetConcrete())"?
Or because we have implementation of ==, != and Equals not only in Entity, but in Organization too?
public abstract class Organization : Entity<int>
{
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public static bool operator ==(Organization object1, Organization object2)
{
return AreEqual(object1, object2);
}
public static bool operator !=(Organization object1, Organization object2)
{
return AreNotEqual(object1, object2);
}
}
public abstract class Entity<TId>
{
public virtual TId Id { get; /*protected*/ set; }
public override bool Equals(object obj)
{
return Equals(obj as Entity<TId>);
}
private static bool IsTransient(Entity<TId> obj)
{
return obj != null &&
Equals(obj.Id, default(TId));
}
private Type GetUnproxiedType()
{
return GetType();
}
public virtual bool Equals(Entity<TId> other)
{
if (other == null)
return false;
if (ReferenceEquals(this, other))
return true;
if (!IsTransient(this) &&
!IsTransient(other) &&
Equals(Id, other.Id))
{
var otherType = other.GetUnproxiedType();
var thisType = GetUnproxiedType();
return thisType.IsAssignableFrom(otherType) ||
otherType.IsAssignableFrom(thisType);
}
return false;
}
public override int GetHashCode()
{
if (Equals(Id, default(TId)))
return base.GetHashCode();
return Id.GetHashCode();
}
/// This method added by me
/// For == overloading
protected static bool AreEqual<TEntity>(TEntity entity1, TEntity entity2)
{
if ((object)entity1 == null)
{
return ((object)entity2 == null);
}
else
{
return entity1.Equals(entity2);
}
}
/// This method added by me
/// For != overloading
protected static bool AreNotEqual<TEntity>(TEntity entity1, TEntity entity2)
{
return !AreEqual(entity1, entity2);
}
}
Related
I'm trying to learn AutoFixture, and I've got xUnit and NSubstitute and AutoFixture setup to automatically mock out properties with fakes (with AutoFixture.AutoNSubstitute). In other words, if I have the following interface
public interface IFoo
{
IBar1 Bar1 {get;}
IBar2 Bar2 {get; set;}
}
Trying to resolve an IFoo will automatically resolve and populate Bar1 and Bar2.
Everything works great for objects with properties of interface, concrete object, or structure types. I'm having a problem getting AutoFixture to automatically create properties of abstract types however.
I have tried using a TypeRelay for the abstract type, so
fixture.Customizations.Add(new TypeRelay(typeof (AbstractBase), typeof (ConcreteChild)));
I have tried specifying it this way,
fixture.Customize<AbstractBase>(
composer =>
composer.FromFactory(
(string ChildParam1, string ChildParam2) => new ConcreteChild(ConcreteChildParam1, ConcreteChildParam2)));
I have tried using various custom specimen builders
Resolving via the property type:
var pi = request as PropertyInfo;
if (pi != null &&
pi.PropertyType == typeof(AbstractBase))
return context.Resolve(typeof(ConcreteChild));
return new NoSpecimen(request);
Resolving via the class type:
var pi = request as Type;
if (pi != null &&
pi == typeof (AbstractBase))
return context.Resolve(typeof(ConcreteChild));
return new NoSpecimen(request);
With both of the above solutions, I also tried context.Create<ConcreteChild>()
Finally I have tried using the Register<AbstractBase>(fixture.Create<ConcreteChild>); syntax.
None of them seem to work as far as automatically populating properties on an object.
The irritating thing is that I can explicitly fixture.Create<AbstractBase>(); in an individual test and get the ConcreteChild and then hand-jam everything but that kind of defeats the purpose of AutoFixture no?
Any ideas?
UPDATE:
The abstract class. I've pruned most of the irrelivent stuff, left the ctor code in as I'm assuming it gets called?
public abstract class ChatEntityId
{
private string _localName;
protected ChatEntityId(string chatRoomName, string entityUid, ChatProtocol protocol)
{
ErrorChecker.NormalizeToNullIfNotSet(ref chatRoomName);
ErrorChecker.NormalizeToNullIfNotSet(ref entityUid);
if (chatRoomName == null && entityUid == null)
{
throw new ArgumentException("Both chatRoomName and entityUid may not be null at the same time.");
}
ChatRoomName = chatRoomName;
EntityUid = entityUid;
Protocol = protocol;
}
public string ChatRoomName { get; private set; }
public string EntityUid { get; private set; }
public bool Equals(ChatEntityId chatEntityId) { }
public override bool Equals(object obj) { }
public override int GetHashCode() {}
public string LocalName { get; }
public ChatProtocol Protocol { get; private set; }
public override string ToString() { }
}
ChatProtocol is an enum, fairly standard.
The AutoPopulatedProperty ICustomization
public virtual void Customize(IFixture fixture)
{
fixture.Customize(new DomainCustomization());
// Replacement for the AutoNSubstituteCustomization, this Postprocessor will automatically create fake objects on properties.
fixture.ResidueCollectors.Add(
new Postprocessor(
new NSubstituteBuilder(
new MethodInvoker(
new NSubstituteMethodQuery())),
new AutoPropertiesCommand(
new PropertiesOnlySpecification())));
}
private class PropertiesOnlySpecification : IRequestSpecification
{
public bool IsSatisfiedBy(object request)
{
return request is PropertyInfo;
}
}
Somewhat embarrassingly, I realized that NSubstitute has what it calls recursive mocking, which is partially what I want and explains why I couldn't figure out where some of the auto-mocked properties were coming from. The problem is that it doesn't do it across the board (probably rightfully so), and isn't really extensible in that regard as far as I can tell.
Now AutoFixture comes into play, after we create the specimen in the Postprocessors NSubstituteBuilder, the AutoPropertiesCommand class is called and fetches what it determines are the appropriate properties to populate with data.
Unfortunately none of the logic in the two relevant classes (there is a non-generic inheriting from a generic AutoPropertiesCommand class) is overridable and this is where the problem occurs. Specifically, AutoPropertiesCommand<T> has two methods it uses to get properties and fields, which it then filters using the supplied IRequestSpecification (PropertiesOnlySpecification in this case).
The method in question
private IEnumerable<PropertyInfo> GetProperties(object specimen)
{
return from pi in this.GetSpecimenType(specimen).GetProperties(BindingFlags.Public | BindingFlags.Instance)
where pi.GetSetMethod() != null
&& pi.GetIndexParameters().Length == 0
&& this.specification.IsSatisfiedBy(pi)
select pi;
}
So the solution here is to either provide my own AutoPropertiesCommand implementation without the above limitations or explicitly create customizations for each case I run across. Haven't decided which approach I like better but probably the former.
As a side-bar it seems kind of restrictive to not have those two methods as protected virtual, is there any particular reason for this beyond "it was just coded that way"? Those are base AutoFixture classes I believe, for the record.
I have a class that implements an interface, such as this:
interface IInterface
{
string PropA { get; }
string PropB { get; }
}
class AClass : IInterface
{
string PropA { get; protected set; }
string PropB { get; protected set; }
}
Equality is determined based on PropA and PropB. When overriding the Equals method for AClass, should I attempt to cast obj to AClass, like this:
public override bool Equals(object obj)
{
AClass other = obj as AClass;
return other != null
&& AClass.PropA == other.PropA
&& AClass.PropB == PropB;
}
Or should I attempt to cast obj to IInterface, like this:
public override bool Equals(object obj)
{
IInterface other = obj as IInterface;
return other != null
&& AClass.PropA == other.PropA
&& AClass.PropB == PropB;
}
You could do whichever you want. The two aren't the same, functionally, but which is "right" for you is something that we can't answer. If I have a BClass class that implements the same interface, and it has the same values for both properties, should it be equal to your AClass object? If yes, do the latter, if not, do the former.
Personally, I would find the latter concerning. Generally I find that if a class is going to implement its own personal definition of equality, other classes shouldn't be equal to it. One main reason is that it's preferable if equality is symetric. That is to say aclass.Equals(bclass) should return the same thing as bclass.Equals(aclass). Getting that behavior when you don't restrict equality to the same type is...hard. It requires cooperation of all related classes.
If you have some compelling reason to be comparing IInterface implementations in which they might be different underlying classes but still both be "equal", I'd personally prefer to create an IEqualityComparer<IInterface> that defines equality for that interface. This would the be separate from the definition of equality for either of the two implementing classes.
Decide how you need it to function.
Resharper implementation:
class AClass : IInterface, IEquatable<AClass>
{
public bool Equals(AClass other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return string.Equals(this.PropA, other.PropA) && string.Equals(this.PropB, other.PropB);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != typeof (AClass)) return false;
return Equals((AClass)obj);
}
public override int GetHashCode()
{
unchecked
{
return ((this.PropA != null ? this.PropA.GetHashCode() : 0) * 397) ^ (this.PropB != null ? this.PropB.GetHashCode() : 0);
}
}
public string PropA { get; protected set; }
public string PropB { get; protected set; }
}
If the purpose of the interface is to hide from consumers the fact that two equivalent objects might be of different classes, it may be a good idea to define a struct which holds a single private field of that interface type and chains to the appropriate methods of the interfaces. Use of such a struct should generally be essentially as efficient as using a variable of the interface type (the main exception would be if the struct ends up being boxed), but would shield client code from seeing the actual type of thing implementing the interface.
For example, one might have a interfaces IReadableMatrix<T> and IImmutableMatrix<T>, and corresponding structures ReadableMatrix<T> and ImmutableMatrix<T> with read-only members int Height, int Width, and T this[int row, int column], and ImmutableMatrix<T> AsImmutable();. Code which uses an ImmutableMatrix<double> shouldn't care how it's stored; it would be entirely possible that two instances of ImmutableMatrix might hold references to different implementations of IImmutableMatrix<T> which report identical content in every cell, but stored things entirely differently. One might be an instance of ArrayBackedMatrix<double>, which holds a 12x12 array that happens to hold zeroes in every element other than those on the diagonal, while the other might be a DiagonalMatrix<double>, and use a 12-item array that only stores things on the diagonal (and returns zero in response to a request for any other element). The use of different types to store the array data should be an implementation detail and not exposed to the client.
One slight detail of using a struct to wrap the arrays is that reference-type fields of a default-value structure will be null, but the structure itself will not. It may thus be desirable to either have the struct implement an IsNull property which returns true if the backing field is null, or else have the other struct members check whether the backing field is null and, if so, behave as an empty 0x0 matrix.
I've implemented every function that MSDN says is necessary, plus some additional comparison interfaces - nothing seems to work. Following is code (optimized for LinqPad).
The resulting output is all 4 items, not 2 like I expect.
Please don't post work arounds as answers - I want to know how Distinct works
void Main()
{
List<NameClass> results = new List<NameClass>();
results.Add(new NameClass("hello"));
results.Add(new NameClass("hello"));
results.Add(new NameClass("55"));
results.Add(new NameClass("55"));
results.Distinct().Dump();
}
// Define other methods and classes here
public class NameClass : Object
, IEquatable<NameClass>
, IComparer<NameClass>
, IComparable<NameClass>
, IEqualityComparer<NameClass>
, IEqualityComparer
, IComparable
{
public NameClass(string name)
{
Name = name;
}
public string Name { get; private set; }
public int Compare(NameClass x, NameClass y)
{
return String.Compare(x.Name, y.Name);
}
public int CompareTo(NameClass other)
{
return String.Compare(Name, other.Name);
}
public bool Equals(NameClass x, NameClass y)
{
return (0 == Compare(x, y));
}
public bool Equals(NameClass other)
{
return (0 == CompareTo(other));
}
public int GetHashCode(NameClass obj)
{
return obj.Name.GetHashCode();
}
public new int GetHashCode()
{
return Name.GetHashCode();
}
public new bool Equals(object a)
{
var x = a as NameClass;
if (null == x) { return false; }
return Equals(x);
}
public new bool Equals(object a, object b)
{
if (null == a && null == b) { return true; }
if (null == a && null != b) { return false; }
if (null != a && null == b) { return false; }
var x = a as NameClass;
var y = b as NameClass;
if (null == x && null == y) { return true; }
if (null == x && null != y) { return false; }
if (null != x && null == y) { return false; }
return x.Equals(y);
}
public int GetHashCode(object obj)
{
if (null == obj) { return 0; }
var x = obj as NameClass;
if (null != x) { return x.GetHashCode(); }
return obj.GetHashCode();
}
public int CompareTo(object obj)
{
if (obj == null) return 1;
NameClass x = obj as NameClass;
if (x == null)
{
throw new ArgumentException("Object is not a NameClass");
}
return CompareTo(x);
}
}
How Distinct works:
There is at least no implementation of Object.GetHashCode() which is used for initial comparison of objects: basic version of Distinct compares (actually puts in dictionary) by Object.GetHashCode first, than if hash code matches by Object.Equals.
To be precise Enumerable.Distinct(this IEnumerable source) uses EqualityComparer<NameClass>.Default to finally check for equality (note that if hash codes don't match it will not reach that portion of the comparison which is why your sample does not work).
The default equality comparer, Default, is used to compare values of the types that implement the IEquatable generic interface.
EqualityComparer.Default in turn actually allows to use class without IEquatable<T> at all falling back directly to Object.Equals:
The Default property checks whether type T implements the System.IEquatable interface and, if so, returns an EqualityComparer that uses that implementation. Otherwise, it returns an EqualityComparer that uses the overrides of Object.Equals and Object.GetHashCode provided by T.
So for basic Distinct to work you just need correct version of Equals/GetHashCode. IEquatable is optional, but must match behavior of GetHashCode in the class.
How to fix:
Your sample have public new int GetHashCode() method, which likely should be public override int GetHashCode() (Same for Equals).
Note that public new int... does not mean "override", but instead "create new version of the method that hides old one". It does not impact callers that call method via pointer to parent object.
Personally I think new should rarely be used in defining methods. Some suggestions when it is useful are covered in Usecases for method hiding using new.
You don't have to implement any interface, just GetHashCode and Equals methods correctly:
public class NameClass
{
public NameClass(string name)
{
Name = name;
}
public string Name { get; private set; }
public override bool Equals(object obj)
{
var other = obj as NameClass;
return other != null && other.Name == this.Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
Enumerable.Distinct<TSource> Method:
It uses the default equality comparer, Default, to compare values.
EqualityComparer.Default:
The Default property checks whether type T implements the System.IEquatable<T> interface and, if so, returns an EqualityComparer<T> that uses that implementation. Otherwise, it returns an EqualityComparer<T> that uses the overrides of Object.Equals and Object.GetHashCode provided by T.
IEquatable<T> Interface:
If you implement IEquatable<T>, you should also override the base class implementations of Object.Equals(Object) and GetHashCode so that their behavior is consistent with that of the IEquatable<T>.Equals method.
Overriding methods:
The override modifier is required to extend or modify the abstract or virtual implementation of an inherited method, property, indexer, or event.
So your code should look like this:
public class NameClass : IEquatable<NameClass>
{
public NameClass(string name)
{
Name = name;
}
public string Name { get; private set; }
// implement IEquatable<NameClass>
public bool Equals(NameClass other)
{
return (other != null) && (Name == other.Name);
}
// override Object.Equals(Object)
public override bool Equals(object obj)
{
return Equals(obj as NameClass);
}
// override Object.GetHashCode()
public override GetHashCode()
{
return Name.GetHashCode();
}
}
So, first off, Distinct will, as per it's documentation, use EqualityComparer<T>.Default to compare objects if no custom equality comparer is provided (you provided none).
EqualityComparer<T>.Default, as per its documentation, will look to see if the object implements IEquatable<T>, if it does it will use that implementation of Equals.
Regardless of whether or not the type implements IEquatable<T>, EqualityComparer<T>.Default will use the object.GetHashCode method to get the has code of the object. IEquatable<T>, unfortunately, does not force you to also override the object's GetHashCode implementation, and in your case, while you do implement IEquatable<T>, your code does not override the object's GetHashCode implementation.
As a result of this Distinct is actually using the proper Equals method for your type, but it's using the wrong GetHashCode method. Whenever you're hashing objects and that type has an Equals and GetHashCode implementation that's out of sync problems ensue. What's happening is that in whatever hash based collection it's sending the two "equal" objects to different buckets, so they never even get to the point where their Equals methods are called on each other. If you happened to get lucky and there was a hash collection and the objects were coincidentally sent to the same bucket, then, since the Equals method is what you intended it would actually work, but the odds of that happening are...very low. (In this specific case, about 2/2147483647, or
9.3e-10.
While you do provide a new GetHashCode method in NameClass, it is hiding the object implementation, not overriding it. If you change your GetHashCode implementation to use override rather than new then your code will work.
I just realized I messed up my sample code - my class derives from DependencyObject, not Object. I can't override thew GetHashCode or Equals functions because the DependencyObject class is sealed.
I have HashSet of my custom class:
public class Vertex
{
public string Name;
public override bool Equals(object obj)
{
var vert = obj as Vertex;
if (vert !=null)
{
return Name.Equals(vert.Name, StringComparison.InvariantCulture);
}
return false;
}
}
And now I have tow hashsets
HashSet<Vertex> hashSet1 = new HashSet<Vertex>();
HashSet<Vertex> hashSet1 = new HashSet<Vertex>();
And now I'd like to have in hashSet1 only Vertexes that are not in hashSet2
So I use ExceptWith method
hashSet1.ExceptWith(hashSet2);
But this doesn't work.
I suppose that this doesn't work because I have complex type.
So the question is: is there some interface required to be implemented in Vertex class to make this thing work?
I know that while creation of HashSet I can pass a EqualityComparer but it seems to me that it would be more elegant to implement some comparing interface method in Vertex class.
Is it possible or I just doesn't understand sth?
Thanks.
When overriding Equals you should also override GetHashCode. HashSet (and other hashing structures like Dictionary) will first calculate a hash code for your objects to locate them in tne structure before comparing elements with Equals.
public override int GetHashCode()
{
return StringComparer.InvariantCulture.GetHashCode(this.Name);
}
You don't have to implement any interface (although IEquatable<T>) is encouraged. When you create a hash-set without specifying an equality-comparer, it defaults to using EqualityComparer<T>.Default, which asks the objects themselves to compare themselves to each other (special-casing null references).
However, in your case, your equality contract is broken since you haven't overriden GetHashCode. Here's how I would fix your type:
public class Vertex : IEquatable<Vertex>
{
public string Name { get; private set; }
public Vertex(string name)
{
Name = name;
}
public override int GetHashCode()
{
return StringComparer.InvariantCulture.GetHashCode(Name);
}
public override bool Equals(object obj)
{
return Equals(obj as Vertex);
}
public bool Equals(Vertex obj)
{
return obj != null && StringComparer.InvariantCulture.Equals(Name, obj.Name);
}
}
Would you mind overriding the .GetHashCode()too?
Here's the reference.
You have to override GetHashCode with Equals overriding.
Object.Equals Method:
Types that override Equals(Object) must also override GetHashCode; otherwise, hash tables might not work correctly.
I'm trying to implement DDD approach in my head.
So far I know that entity is unique and identified by combination of its attributes.
Entity is abstract class which will be implemented by other entity classes.
I know so far that Version property is used to manage concurrency.
Need help with rest of this class.
I'm in process of learning DDD so please describe your thoughts on this or share useful concrete theme links.
public abstract class Entity<T>
{
#region Properties
protected T _Id;
private int _Version;
#endregion
private static bool IsTransient(Entity<T> obj)
{
return (obj != null) &&
Equals(obj.Id, default(T));
}
private Type GetUnproxiedType()
{
return GetType();
}
public virtual T Id
{
get
{
return _Id;
}
protected set
{
_Id = value;
}
}
public virtual int Version
{
get
{
return _Version;
}
set
{
_Version = value;
}
}
public override bool Equals(object obj)
{
return Equals(obj as Entity<T>);
}
public virtual bool Equals(Entity<T> other)
{
if (other == null) return false;
if (ReferenceEquals(this, other)) return true;
if (!IsTransient(this) &&
!IsTransient(other) &&
Equals(Id, other.Id))
{
var otherType = other.GetUnproxiedType();
var thisType = GetUnproxiedType();
return (thisType.IsAssignableFrom(otherType)
|| otherType.IsAssignableFrom(thisType));
}
return false;
}
public override int GetHashCode()
{
if (Equals(Id, default(T)))
{
return base.GetHashCode();
}
return Id.GetHashCode();
}
public static bool operator ==(Entity<T> e1, Entity<T> e2)
{
return Equals(e1, e2);
}
public static bool operator !=(Entity<T> e1, Entity<T> e2)
{
return !Equals(e1, e2);
}
}
Updated
After some researching I'm concluded with this
Using Equals method will come handy when we try to compare two objects. For example imaging place in application where we have the same object in more than one instance. One from the database and one from the client. We need to find out if that object is identical and yet not the same.
For this we will be using Equals method.
An entity is not uniquely identified by the value of its attributes; An entity has an identity, but that does not mean that the identity is made up by the value of its attributes.
That would mean that, if you change one if the attributes of an entity, it's identity will change, and you do not want that behaviour.
(For instance, if your address changes, your identity doesn't change, you're still the same person, living at another address).
(I see that you've implemented identity/equality by using an Id property, which is a good thing).
Next to entities, you have value - objects. The identity of a value object is made up by the values of its attributes, and therefore, it is better that a value object is immutable, since, changing the value object would also mean that you change its identity.
But, what is your question ?