I have been working on a generic method to compare two of the same objects to test wether the values in each one are equal.
我一直在研究一种通用的方法来比较两个相同的对象,以测试每个对象中的值是否相等。
I am stuck on trying to compare System.Collection.Generic objects, such as Dictionary, HashSet, LinkedList, Stack, ect...
我坚持尝试比较System.Collection.Generic对象,如Dictionary,HashSet,LinkedList,Stack等...
The one i can compare on is the List collection.
我可以比较的是List集合。
Below is what I have so far. if you can provide a means to compare the generics I'd be greatly appreciative.
以下是我到目前为止的情况。如果你能提供一种比较仿制药的方法,我将非常感激。
~Starts the recursive compare
〜开始递归比较
public static bool FullCompare<T>(this T source, T compareTo, bool ignoreCase)
{
return recursiveCompare(source, compareTo, ignoreCase, true);
}
~The recursive search
〜递归搜索
private static bool recursiveCompare<T>(T source, T compareTo, bool ignoreCase, bool isEqual)
{
if (source == null || compareTo == null) return isEqual;
if(!isEqual) return isEqual;
Type sourceType = source.GetType();
Type compareToType = compareTo.GetType();
if (sourceType.IsPrimitive || source is string) return Test(source, compareTo, ignoreCase);
var sourceProperties = sourceType.GetProperties();
var compareToProperties = compareToType.GetProperties();
for (var property = 0; property < sourceProperties.Count(); property++ )
{
var sourceProperty = sourceProperties[property];
var compareToProperty = compareToProperties[property];
object sourceValue = sourceProperty.GetValue(source, null);
object compareToValue = compareToProperty.GetValue(compareTo, null);
var sourceElements = sourceValue as IList;
var compareToElements = compareToValue as IList;
if (sourceElements != null)
{
for (var element = 0; element < sourceElements.Count; element++)
{
isEqual = recursiveCompare(sourceElements[element], compareToElements[element], ignoreCase, isEqual);
}
}
else if (typeof(IEnumerable).IsAssignableFrom(sourceProperty.PropertyType))
{
//compare System.Collection.Generic objects
}
else
{
if (sourceProperty.PropertyType.Assembly == sourceType.Assembly)
{
isEqual = recursiveCompare(sourceValue, compareToValue, ignoreCase, isEqual);
}
else
{
isEqual = Test(sourceValue, compareToValue, ignoreCase);
}
}
}
return isEqual;
}
~ The comparison test
〜比较测试
private static bool Test<T>(T a, T b, bool ignoreCase)
{
if (a == null && b == null)
{
return true;
}
else if (a == null)
{
return false;
}
else if (b == null)
{
return false;
}
else if (a is string)
{
if (ignoreCase)
{
var aAsString = Convert.ToString(a);
var bAsString = Convert.ToString(b);
return aAsString.EqualsIgnoreCaseAndWhitespace(bAsString);
}
}
return EqualityComparer<T>.Default.Equals(a, b);
}
These are the test cases I am using to test the function
这些是我用来测试函数的测试用例
public class A
{
public string TestA { get; set; }
public List<String> ListA { get; set; }
}
public class test
{
public byte? byte1 { get; set; }
//public Dictionary<int, byte> byteDictionary { get; set; }
public HashSet<byte> byteHashSet { get; set; }
public LinkedList<byte> byteLinkedList { get; set; }
public List<byte> byteList { get; set; }
public Queue<byte> byteQueue { get; set; }
public Stack<byte> byteStack { get; set; }
public sbyte? sbyte1 { get; set; }
public short? short1 { get; set; }
public ushort? ushort1 { get; set; }
public int? int1 { get; set; }
public uint? uint1 { get; set; }
public long? long1 { get; set; }
public ulong? ulong1 { get; set; }
public float? float1 { get; set; }
public double? double1 { get; set; }
public char? char1 { get; set; }
public string string1 { get; set; }
public decimal? decimal1 { get; set; }
public bool? bool1 { get; set; }
public DateTime datetime1 { get; set; }
public TimeSpan timespan1 { get; set; }
public string string1Var;
public A objectA { get; set; }
}
var byteAList = new List<byte>();
byteAList.Add(1);
byteAList.Add(2);
var byteBList = new List<byte>();
byteBList.Add(1);
byteBList.Add(2);
//var byteADictionary = new Dictionary<int,byte>();
//byteADictionary.Add(1,1);
//var byteBDictionary = new Dictionary<int,byte>();
//byteBDictionary.Add(1,1);
var dateTimeA = new DateTime(1,1,1,1,1,1);
var dateTimeB = new DateTime(1,1,1,1,1,1);
var timeSpanA = new TimeSpan(1,1,1,1,1);
var timeSpanB = new TimeSpan(1,1,1,1,1);
var aAListAList = new List<string>();
aAListAList.Add("Nel");
aAListAList.Add("Hello");
var aA = new A()
{
TestA = "Jar"
, ListA = aAListAList
};
var aAListBList = new List<string>();
aAListBList.Add("Nel");
aAListBList.Add("Hello");
var aB = new A()
{
TestA = "Jar"
,
ListA = aAListBList
};
var byteHashSetA = new HashSet<byte>();
byteHashSetA.Add(1);
byteHashSetA.Add(2);
var byteHashSetB = new HashSet<byte>();
byteHashSetB.Add(1);
byteHashSetB.Add(2);
var a = new test()
{
byte1 = 1
, byteList = byteAList
//, byteDictionary = byteADictionary
, byteHashSet = byteHashSetA
, sbyte1 = -1
, short1 = -11
, ushort1 = 11
, int1 = -1
, uint1 = 1
, long1 = 1
, ulong1 = 1
, float1 = 1.1F
, double1 = 1.1
//, char1 = 't'
, string1 = "test"
, decimal1 = 1.1M
, bool1 = true
, datetime1 = dateTimeA
, timespan1 = timeSpanA
, string1Var = null
, objectA = aA
};
var a2 = new test()
{
byte1 = 1
,
byteList = byteBList
//,
//byteDictionary = byteBDictionary
,
byteHashSet = byteHashSetB
,
sbyte1 = -1
,
short1 = -11
,
ushort1 = 11
,
int1 = -1
,
uint1 = 1
,
long1 = 1
,
ulong1 = 1
,
float1 = 1.1F
,
double1 = 1.1
,
char1 = 't'
,
string1 = "test"
,
decimal1 = 1.1M
,
bool1 = true
,
datetime1 = dateTimeB
,
timespan1 = timeSpanB
,
string1Var = null
,
objectA = aB
};
var equal = a.FullCompare(a2, true);
1 个解决方案
#1
0
I solved the issue by comparing the lengths of the two objects first. then if they are the same then i do a nested loop to compare one list against the other. now this is probably not efficient, but it works.
我首先通过比较两个对象的长度来解决问题。然后,如果它们是相同的,那么我做一个嵌套循环来比较一个列表与另一个列表。现在这可能效率不高,但它确实有效。
foreach (var sourceElement in sourceElements) { numOfSourceElements++; }
foreach (var compareToElement in compareToElements) { numOfCompareToElements++; }
if (numOfSourceElements != numOfCompareToElements) isEqual = false;
if (isEqual)
{
foreach (var sourceElement in sourceElements)
{
found = false;
foreach (var compareToElement in compareToElements)
{
if (IsSameAsRecursive(sourceElement, compareToElement, sameAsOptions, isEqual))
{
found = true;
break;
}
}
if (!found) break;
}
isEqual = found;
}
#1
0
I solved the issue by comparing the lengths of the two objects first. then if they are the same then i do a nested loop to compare one list against the other. now this is probably not efficient, but it works.
我首先通过比较两个对象的长度来解决问题。然后,如果它们是相同的,那么我做一个嵌套循环来比较一个列表与另一个列表。现在这可能效率不高,但它确实有效。
foreach (var sourceElement in sourceElements) { numOfSourceElements++; }
foreach (var compareToElement in compareToElements) { numOfCompareToElements++; }
if (numOfSourceElements != numOfCompareToElements) isEqual = false;
if (isEqual)
{
foreach (var sourceElement in sourceElements)
{
found = false;
foreach (var compareToElement in compareToElements)
{
if (IsSameAsRecursive(sourceElement, compareToElement, sameAsOptions, isEqual))
{
found = true;
break;
}
}
if (!found) break;
}
isEqual = found;
}