c# compare two generic values [duplicate]
Asked Answered
G

4

92

Possible Duplicate:
Can’t operator == be applied to generic types in C#?

I've coded something like this:

public bool IsDataChanged()
{           
    T value1 = GetValue2;
    T value2 = GetValue1();

    return (valueInDB != valueFromView);
}

Right now the function doesn't compile with the error "Operator '!=' cannot be applied to operands of type 'T' and 'T'". What do I have to do to make this function work ?

Gambrell answered 28/1, 2009 at 16:19 Comment(2)
Dup of #391400Blakely
And #337384Septet
A
167

You cannot use operators on generic types (except for foo == null which is special cased) unless you add where T : class to indicate it is a reference type (then foo == bar is legal)

Use EqualityComparer<T>.Default to do it for you. This will not work on types which only supply an operator overload for == without also either:

  • implement IEquatable<T>
  • overrides object.Equals()

In general implementing the == operator and not also doing at least one of these would be a very bad idea anyway so this is not likely to be an issue.

public bool IsDataChanged<T>()
{           
    T value1 = GetValue2;
    T value2 = GetValue1();

    return !EqualityComparer<T>.Default.Equals(value1 , value2);
}

If you do not restrict to IEquatable<T> then the EqualityComparer default fallback may cause boxing when used with value types if they do not implement IEquatable<T> (if you control the types which are being used this may not matter). I am assuming you were using =! for performance though so restricting to the Generic type will avoid accidental boxing via the Object.Equals(object) route.

Alienate answered 28/1, 2009 at 16:26 Comment(6)
Actually, you don't need the T : IEquatable<T> restriction - it works without it, using .EqualsOcto
Re operators, you can via www.pobox.com/~skeet/csharp/miscutil/usage/genericoperators.htmlOcto
thanks for the operators link but I felt it worth pointing out that you cannot use the operators, you have to jump through some sort of hoop to achieve the same behaviout. the MiscUtils ones are jyst very nice hoops :) I pointed out the reasons to keep the restriction even though you don't have to.Alienate
Sorry, but the reasoning is incorrect; the constraint is unnecessary and a burdenOcto
It's unnecessary to correctness you're right, I will edit to make that clearAlienate
Shouldn't value1 and value2 be valueInDB and valueFromView?Intermolecular
B
9

That should work for you.

public bool test<T>(T test, T test2) where T : class
{
    return (test != test2);
}

This is simply pasted from the examples that were commented on your question.

Bellyache answered 28/1, 2009 at 16:25 Comment(4)
Even if the accepted answer is more complete, this solution is definitely the easiest one to solve the problem.Echikson
This only does Object.ReferenceEquals(test, test2). It doesn't check for value equality.Armin
I can use this option in razor component defining the component in this way: @typeparam TValue where TValue : classReitareiter
That where T: class really cleans up a lot of annoying boilerplate I was using around generics, super handy!Vaporific
W
5

Your type needs to implement the IComparable or IEquatable interface.

Probably you then need to rewrite a!=b as !(a==b), or call the CompareTo() or Equals() method explicitly.

Washcloth answered 28/1, 2009 at 16:25 Comment(0)
A
1

You can overload the .Equals() method on your objects and change your evaluation to:

return (!valueInDB.Equals(valueFromView));

Assuming that valueInDB and valueFromView are objects. Your example variables aren't named the same as those used in the compare, so I had to assume.

EDIT: Got beat by 3 seconds! A note on overloading, if you need to compare values within a type, the basic .Equals() from the Object class won't be enough, as it will only do a memory compare for complex types. You'll need to overload and provide the implementation of how you want the object to be compared.

Aguirre answered 28/1, 2009 at 16:25 Comment(1)
Careful of the null reference exception.Excretion

© 2022 - 2024 — McMap. All rights reserved.