tags:

views:

5195

answers:

5

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 ?

A: 

That should work for you. public bool test(T test, T test2) where T : class { return (test != test2); }

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

CalvinR
A: 

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.

Jay S
+3  A: 

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.

devio
+19  A: 

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(valueInDB, valueFromView);
}

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.

ShuggyCoUk
Actually, you don't need the T : IEquatable<T> restriction - it works without it, using .Equals
Marc Gravell
Re operators, you can via www.pobox.com/~skeet/csharp/miscutil/usage/genericoperators.html
Marc Gravell
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.
ShuggyCoUk
Sorry, but the reasoning is incorrect; the constraint *is* unnecessary and a burden
Marc Gravell
It's unnecessary to correctness you're right, I will edit to make that clear
ShuggyCoUk
A: 

Genric is nothing its a genrelized form for other types defined in .net so copare values in generic 1. You needs to implement the IComparable or IEquatable interface. 1. Use .Equals(),.CompareTo methods that will helpful to us

Try yourself

That is simply incorrect. See the accepted answer; you can perform both equality and comparison operations on generics using Comparer<T> and EqualityComparer<T>, which know about the common interfaces and patterns.
Marc Gravell