Comparing 2 user objects - C #

I need to write a general method in a base class that would take 2 objects as parameters and compare them for equality.

Example:

public abstract class BaseData { public bool AreEqual(object O1, object O2) { //Need to implement this } } public class DataTypeOne : BaseData { public string Name; public string Address; } public class DataTypeTwo : BaseData { public int CustId; public string CustName; } 

The AreEqual() method accepts two instances of DataTypeOne or 2 instances of DataTypeTwo .

I assume I need to use Reflection? I can use LINQ if it can be more readable / concise.

EDIT: The reason I would like to implement this method in the base class is due to the limitations of the project. A large number of developers work on derived classes. By implementing this in the base class, I try to be less concerned about them.

+6
c #
source share
6 answers

(Assuming you want to compare all fields of two objects for equality.)

As a rule, you would not use reflection for this, you would simply compare each field yourself. An IEquatable<T> interface exists for this purpose, and you can also override Object.Equals() for the types in question. For example:

 public class DataTypeTwo : BaseData, IEquatable<DataTypeTwo> { public int CustId; public string CustName; public override int GetHashCode() { return CustId ^ CustName.GetHashCode(); // or whatever } public override bool Equals(object other) { return this.Equals(other as DataTypeTwo); } public bool Equals(DataTypeTwo other) { return (other != null && other.CustId == this.CustId && other.CustName == this.CustName); } } 

Also, consider if your type makes sense as a struct . Value types automatically compare equality by conducting field comparisons.

Note that by overriding Equals , you basically achieve what (it seems to me) that you are trying to achieve using your equal method method with your scheme. That is, people using DataTypeTwo will naturally be able to test equality without knowing anything special about your API, they will just use Equals as if they were with other things.

EDIT: Thanks to Jared for reminding me of GetHashCode . You will also want to override it to maintain normal behavior in the hash tables, making sure that any two "equal" objects return the same hash code.

+13
source share

This is what I came up with using reflection. Hope it helps.

 public bool AreEqual(object obj) { bool returnVal = true; if (this.GetType() == obj.GetType()) { FieldInfo[] fields = this.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); foreach (FieldInfo field in fields) { if(field.GetValue(this) != field.GetValue(obj)) { returnVal = false; break; } } } else returnVal = false; return returnVal; } 
+4
source share

Do not do this. Inheritance is the way to go, and each class, if necessary, must override Equal and GetHashCode.

You may now do some work on these developers, but I will come back to bite you in the ass in the future when the product needs to be saved .

Seriously, just try to find another way to help.
+2
source share

I would probably do something like this:

 public abstract class BaseData : IEquatable<BaseData> { public abstract bool Equals(BaseData other); } public class DataTypeOne : BaseData { public string Name; public string Address; public override bool Equals(BaseData other) { var o = other as DataTypeOne; if(o == null) return false; return Name.Equals(o.Name) && Address.Equals(o.Address); } } public class DataTypeTwo : BaseData { public int CustId; public string CustName; public override bool Equals(BaseData other) { var o = other as DataTypeTwo; if (o == null) return false; return CustId == o.CustId && CustName.Equals(o.CustName); } } 
+1
source share

Yes, you will have to use reflection because the base class knows nothing about derived classes. But why do you want to implement this function in a base class? Why not in derived classes?

Further, there is a standard way to do this by overriding Object.GetHashCode () and Object.Equals ().

0
source share
 public void CompareTwoObjects() { try { byte[] btArray = ObjectToByteArray(object1); //object1 is you custom object1 byte[] btArray2 = ObjectToByteArray(object2); //object2 is you custom object2 bool result = ByteArrayCompare(btArray, btArray2); } catch (Exception ex) { throw ex; } } public byte[] ObjectToByteArray(object _Object) { try { // create new memory stream System.IO.MemoryStream _MemoryStream = new System.IO.MemoryStream(); // create new BinaryFormatter System.Runtime.Serialization.Formatters.Binary.BinaryFormatter _BinaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); // Serializes an object, or graph of connected objects, to the given stream. _BinaryFormatter.Serialize(_MemoryStream, _Object); // convert stream to byte array and return return _MemoryStream.ToArray(); } catch (Exception _Exception) { // Error Console.WriteLine("Exception caught in process: {0}", _Exception.ToString()); } // Error occured, return null return null; } public bool ByteArrayCompare(byte[] a1, byte[] a2) { if (a1.Length != a2.Length) return false; for (int i = 0; i < a1.Length; i++) if (a1[i] != a2[i]) return false; return true; } 
0
source share

All Articles