using System.Collections.Generic;
public static void Main()
Cliente cliente1 = new Cliente(1, "Fabricio");
Cliente cliente2 = new Cliente(2, "Fabricio");
if(cliente1.Endereco == cliente2.Endereco)
Console.WriteLine("Enderecos iguais!!!!");
Console.WriteLine("Enderecos diferentes!!!!");
Console.WriteLine("Usando igual: ");
Console.WriteLine(cliente1.Endereco == cliente2.Endereco);
Console.WriteLine("Usando EQUALS: ");
Console.WriteLine(cliente1.Endereco.Equals(cliente2.Endereco));
public class Endereco : ValueObject
public Endereco(string rua, int numero)
public string Rua {get; set;}
public int Numero {get; set;}
public Cliente(int id, string nome)
Endereco = new Endereco("teste", 100);
public int Id {get; set;}
public string Nome {get; set;}
public Endereco Endereco {get; set;}
public class ValueObject : IEquatable<ValueObject>
private List<PropertyInfo> _properties;
private List<FieldInfo> _fields;
public static bool operator ==(ValueObject obj1, ValueObject obj2)
return !Equals(obj1, null) ? obj1.Equals(obj2) : Equals(obj2, null);
public static bool operator !=(ValueObject obj1, ValueObject obj2)
public bool Equals(ValueObject obj)
return Equals(obj as object);
public override bool Equals(object obj)
if (obj == null || GetType() != obj.GetType()) return false;
return GetProperties().All(p => PropertiesAreEqual(obj, p))
&& GetFields().All(f => FieldsAreEqual(obj, f));
private bool PropertiesAreEqual(object obj, PropertyInfo p)
return Equals(p.GetValue(this, null), p.GetValue(obj, null));
private bool FieldsAreEqual(object obj, FieldInfo f)
return Equals(f.GetValue(this), f.GetValue(obj));
private IEnumerable<PropertyInfo> GetProperties()
return this._properties ?? (this._properties = GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList());
private IEnumerable<FieldInfo> GetFields()
return this._fields ?? (_fields = GetType().GetFields(BindingFlags.Instance | BindingFlags.Public).ToList());