Revils
Revils

Reputation: 1508

Compare T to Int64 or Double

I have the a method with the following signature;

private static void CheckValue<T>(ref Double result, Int64 value, String condition, T checkValue) where T : class{};

The checkValue can be a Double or an Int64. However it gives the following error;

Operator '>=' cannot be applied to operatands of type 'long' and 'T'

Because I want a generic function and do not want to define two functions (One with the Int64 checkValue and one with the Double checkValue signature), I came up with T.

I used the where T : class, this way it limits T to classes and can use operators. (Found this on the following topic): How to solve Operator '!=' cannot be applied to operands of type 'T' and 'T'

I can imagine that this works if I can restrain T to only Int64 or Double. However if I change the following in the signature:

where T : class, Int64, Double

It gives the same error.

@Edit - 06-08-2015 11:16 My bad, If I run the prior it gives an error about the Int64 and Double in the where clause. (It is not a valid constraint)

Upvotes: 0

Views: 234

Answers (2)

Jon Hanna
Jon Hanna

Reputation: 113332

The checkValue can be a Double or an Int64

No it can't. You've got where T : class as a constraint to insist that T is a reference type, so T can be neither of those things. You in fact what to insist upon the opposite:

private static void CheckValue<T>(ref Double result, Int64 value, String condition, T checkValue) where T : struct
{
}

Operator '>=' cannot be applied to operatands of type 'long' and 'T'

Well it can't. You need to have a specific type which >= can be used with.

You can though depend upon the fact that both long and double implement IComparable. I've no idea what you actually want to do in your implementation, but the following works:

private static void CheckValue<T>(ref Double result, Int64 value, String condition, T checkValue) where T : struct, IComparable
{
  if(checkValue is long)
    result = checkValue.CompareTo(value) >= 0 ? 1.0 : -1.0;
  else if(checkValue is double)
    result = checkValue.CompareTo((double)value) >= 0 ? 1.0 : -1.0;
  else
    throw new Invalid‎OperationException();
}

Because I want a generic function and do not want to define two functions (One with the Int64 checkValue and one with the Double checkValue signature), I came up with T.

While the above works, I'd recommend you do have separate methods here. The result will be faster (no runtime check on type, and faster comparison call) and more type-safe (no chance of the runtime check on type failing). It's worth noting for comparison that many framework methods have overloads on different primitive types, even in methods that were first introduced to the framework after generics where added to .NET, for these reasons.

(I'd also note that using ref is often best avoided, especially since you aren't returning any other value forcing you into using ref. Could you instead accept Double result and return a double, with the replacement of the value happening where the call is made rather than inside this method?)

Upvotes: 1

Kiran Syeed
Kiran Syeed

Reputation: 71

There is no need to implement it using generics as you are comparing a double or an int with an Integer value. But if you some implementation with generics , then Just have a signature like this.

 private static void CheckValue<T>(ref Double result, int value, String condition, T checkValue) where T : struct
        {
            if (value.Equals(checkValue))
                result=1; // do anything you want here
            else
                result=0;
        }

Upvotes: 0

Related Questions