Reputation: 836
I am trying to write a generic method to compare two objects (I purposefully have two different types coming in. The second one has the same properties as the first one. The first just has more.).
I want to make sure the properties have the same values. The following code works for most of the properties that I have in the objects, but occasionally it throws the:
"Object Does Not Match Target Type"
...error at
var valFirst = prop.GetValue(manuallyCreated, null) as IComparable;
public static bool SameCompare<T, T2>(T manuallyCreated, T2 generated){
var propertiesForGenerated = generated.GetType().GetProperties();
int compareValue = 0;
foreach (var prop in propertiesForGenerated) {
var valFirst = prop.GetValue(manuallyCreated, null) as IComparable;
var valSecond = prop.GetValue(generated, null) as IComparable;
if (valFirst == null && valSecond == null)
continue;
else if (valFirst == null) {
System.Diagnostics.Debug.WriteLine(prop + "s are not equal");
return false;
}
else if (valSecond == null) {
System.Diagnostics.Debug.WriteLine(prop + "s are not equal");
return false;
}
else if (prop.PropertyType == typeof(System.DateTime)) {
TimeSpan timeDiff = (DateTime)valFirst - (DateTime)valSecond;
if (timeDiff.Seconds != 0) {
System.Diagnostics.Debug.WriteLine(prop + "s are not equal");
return false;
}
}
else
compareValue = valFirst.CompareTo(valSecond);
if (compareValue != 0) {
System.Diagnostics.Debug.WriteLine(prop + "s are not equal");
return false;
}
}
System.Diagnostics.Debug.WriteLine("All values are equal");
return true;
}
Upvotes: 4
Views: 8402
Reputation: 1078
I believe it would be better to have Interface of the properties you need to compare,
I would then inherit IEqualityComparer<YourInterface>
and in Equals and GetHashCode
public bool Equals(YourInterface one, YourInterface two)
{
return this.GetHashCode(one) == this.GetHashCode(two);
}
public int GetHashCode(YourInterface test)
{
if(test == null)
{
return 0;
}
int hash = 0;
//// get hash or set int on each property.
return hash;
}
Upvotes: 0
Reputation: 148980
Each property defined on a type in .NET is different, even if they have the same name. You'd have to do this:
foreach (var prop in propertiesForGenerated)
{
var otherProp = typeof(T).GetProperty(prop.Name);
var valFirst = otherProp.GetValue(manuallyCreated, null) as IComparable;
var valSecond = prop.GetValue(generated, null) as IComparable;
...
Of course this doesn't take into account that some properties defined on T
may not exist on T2
, and vice versa.
Upvotes: 3
Reputation: 87218
Because manuallyCreated
is not of type T2
. Try getting the property object with the same name on that type, and it should work (or if your assumption that all properties in T2 are also in T1, you'll get a better error):
public static bool SameCompare<T, T2>(T manuallyCreated, T2 generated){
var propertiesForGenerated = typeof(T2).GetProperties();
int compareValue = 0;
foreach (var prop in propertiesForGenerated) {
var firstProperty = typeof(T).GetProperty(prop.Name);
var valFirst = firstProperty.GetValue(manuallyCreated, null) as IComparable;
var valSecond = prop.GetValue(generated, null) as IComparable;
...
}
}
Upvotes: 0