Dan Burgener
Dan Burgener

Reputation: 836

C# - GetValue - Object Does Not Match Target Type

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

Answers (3)

Bit
Bit

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

p.s.w.g
p.s.w.g

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

carlosfigueira
carlosfigueira

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

Related Questions