public static IgnoreList Create(params string[] names) { var ignore = new IgnoreList(); ignore.Add(names); return ignore; }
public static IgnoreList Create(Dictionary<Type, string[]> ignoreList) { var ignore = new IgnoreList(); foreach (var map in ignoreList) { ignore.Add(map.Key, map.Value); } return ignore; }
/// <summary> /// Compares the properties of two objects of the same type and returns if all properties are equal. /// </summary> /// <param name="objectA">The first object to compare.</param> /// <param name="objectB">The second object to compre.</param> /// <param name="ignoreList">A Dictionary to ignore from the comparison where keys is type and vae is list of property names </param> /// <returns><c>true</c> if all property values are equal, otherwise <c>false</c>.</returns> public static bool AreObjectsEqual(object objectA, object objectB, IgnoreList ignoreList = null) { bool result; if (objectA != null && objectB != null) { Type objectType; objectType = objectA.GetType(); result = true; // assume by default they are equal foreach (PropertyInfo propertyInfo in objectType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead && !IsPresentInIgnoreList(ignoreList, objectType, p))) { object valueA; object valueB; ParameterInfo[] par = propertyInfo.GetIndexParameters(); if (par.Length > 0) { //we shouldn't compare indexed properties continue; } valueA = propertyInfo.GetValue(objectA, null); valueB = propertyInfo.GetValue(objectB, null); // if it is a primative type, value type or implements IComparable, just directly try and compare the value if (CanDirectlyCompare(propertyInfo.PropertyType)) { if (!AreValuesEqual(valueA, valueB)) { Console.WriteLine("Mismatch with property '{0}.{1}' found.", objectType.FullName, propertyInfo.Name); result = false; } } // if it implements IEnumerable, then scan any items else if (typeof(IEnumerable).IsAssignableFrom(propertyInfo.PropertyType)) { IEnumerable<object> collectionItems1; IEnumerable<object> collectionItems2; int collectionItemsCount1; int collectionItemsCount2; // null check if (valueA == null && valueB != null || valueA != null && valueB == null) { Console.WriteLine("Mismatch with property '{0}.{1}' found.", objectType.FullName, propertyInfo.Name); result = false; } else if (valueA != null && valueB != null) { collectionItems1 = ((IEnumerable)valueA).Cast<object>(); collectionItems2 = ((IEnumerable)valueB).Cast<object>(); collectionItemsCount1 = collectionItems1.Count(); collectionItemsCount2 = collectionItems2.Count(); // check the counts to ensure they match if (collectionItemsCount1 != collectionItemsCount2) { Console.WriteLine("Collection counts for property '{0}.{1}' do not match.", objectType.FullName, propertyInfo.Name); result = false; } // and if they do, compare each item... this assumes both collections have the same order else { for (int i = 0; i < collectionItemsCount1; i++) { object collectionItem1; object collectionItem2; Type collectionItemType; collectionItem1 = collectionItems1.ElementAt(i); collectionItem2 = collectionItems2.ElementAt(i); collectionItemType = collectionItem1.GetType(); if (CanDirectlyCompare(collectionItemType)) { if (!AreValuesEqual(collectionItem1, collectionItem2)) { Console.WriteLine("Item {0} in property collection '{1}.{2}' does not match.", i, objectType.FullName, propertyInfo.Name); result = false; } } else if (!AreObjectsEqual(collectionItem1, collectionItem2, ignoreList)) { Console.WriteLine("Item {0} in property collection '{1}.{2}' does not match.", i, objectType.FullName, propertyInfo.Name); result = false; } } } } } else if (propertyInfo.PropertyType.IsClass) { if (!AreObjectsEqual(propertyInfo.GetValue(objectA, null), propertyInfo.GetValue(objectB, null), ignoreList)) { Console.WriteLine("Mismatch with property '{0}.{1}' found.", objectType.FullName, propertyInfo.Name); result = false; } } else { Console.WriteLine("Cannot compare property '{0}.{1}'.", objectType.FullName, propertyInfo.Name); result = false; } } } else result = object.Equals(objectA, objectB); return result; }
private static bool IsPresentInIgnoreList(IgnoreList ignoreList, Type type, PropertyInfo propertyInfo) { if (ignoreList == null) return false; if (ignoreList.WithTypes.ContainsKey(type)) { string[] props = ignoreList.WithTypes[type]; return props.Any(prop => prop == propertyInfo.Name); } if (ignoreList.NamesOnly.Count > 0) { return ignoreList.NamesOnly.Contains(propertyInfo.Name); } return false; }