Reputation: 677
See code below. There is a squigley red line under first > second Operator cannot be applied to operands OBJ and OBJ.
Is there some easy way to do what is intended here?
public static OBJ Swap<OBJ>(ref OBJ first, ref OBJ second) where OBJ : IComparable
{
OBJ temp = first;
OBJ temp2 = second;
second = temp;
first = temp2;
if (first > second) return first else return second;
}
Upvotes: 0
Views: 233
Reputation: 37020
The reason you're getting that compile-time error is that the only restriction you've placed on the type is that it implements IComparable
, the only method that interface guarantees is the CompareTo
method, and not all types implement the comparison operators.
Since CompareTo
is guaranteed to be available, however, you can use that instead.
Also note that you should use the null conditional operator (?.
) when calling the CompareTo
method, since there's the possibility that first
is null
(in which case, calling .CompareTo
will throw an ArgumentNullException
).
The rest of your code can also be slightly simplified. First, you can shorten it slightly by using the ternary operator (?:
) when deciding which item to return. And second, in a swap operation you only need a single temp
variable to hold the value of the first variable you re-assign. For example:
public static T Swap<T>(ref T first, ref T second) where T : IComparable
{
var temp = first;
first = second;
second = temp;
return first?.CompareTo(second) > 0 ? first : second;
}
Here's a case where the null
value would otherwise throw an exception, but with the code above it works as expected:
string first = null;
string second = "2";
string largest = Swap(ref first, ref second);
Upvotes: 2
Reputation: 38767
If (i > j) works because int supports IComparable.
Nope. This is incorrect. It works because it implements comparison operators. For example:
public static bool operator >(MyClass l, MyClass r) {
return l.Value > r.Value;
}
This is unrelated to IComparable which requires that a single instance method be defined in implementing classes:
public int CompareTo(object obj) {
It is entirely possible to create a class what implements IComparable without comparison operators, or vice versa.
All you are saying with public static OBJ Swap<OBJ>(ref OBJ first, ref OBJ second) where OBJ : IComparable
is that OBJ should implement IComparable
- there is nothing implied that the type passed here will have comparison operators defined. Because of this, the compiler can't allow you to perform equality comparisons on objects that may not have comparison operators defined.
I know you're thinking "but the compiler can work out what I've passed at compile time", but remember that your compiled application (even in .exe form) could be referenced by an external application which could pass an invalid type.
You should instead use CompareTo
:
return a.CompareTo(b) > 0 ? a : b;
Upvotes: 1