3

The following code does not compile with

... cannot convert T to int bla bla bla

bool IsEqual<T>(this T a, T b, T offset)
{
    a = Math.Abs(a);
    b = Math.Abs(b);
    if (Math.Abs(a - b) < offset)
        return true;
    else
        return false;
}

How to use Math.Abs inside my own generic method?

kiss my armpit
  • 3,413
  • 1
  • 27
  • 50
  • 3
    You can't. You'll need to just provide a set of overloads and some very repetitive code for the types that `Math.Abs` actually supports (or the smaller subset of types that you want to work with) – Damien_The_Unbeliever Feb 28 '14 at 07:21

2 Answers2

1

You can't. In your method the type parameter T could be anything, a string, a class, you name it.

Math.Abs exists only for a small set of parameter types. It would be nice if you could constraint T to them, but that's not possible either.

That means if you need the IsEqual method to work with different types of T you will have to write the overloads for them manually:

bool IsEquals(int a, int b, int offset) { }
bool IsEquals(double a, double b, double offset) { }
// and many more
Dirk
  • 10,668
  • 2
  • 35
  • 49
  • can we use extension method here? – kiss my armpit Feb 28 '14 at 07:26
  • You can make them extension methods of course, but that won't solve the problem. – Dirk Feb 28 '14 at 07:28
  • @TheLastError the problem is that whether you use extension methods or not you will have to constraint T to something or Math.Abs(a) won't compile, but that constraint is simply not possible because the C# spec won't allow it. And the constraint would also have to include that an `operator -` exists on `T`. – Dirk Feb 28 '14 at 07:31
1

If only .Net had class or interface like Number in Java, you could well have put something like

 // Doesn't compile; just the idea
 bool IsEqual<T>(this T a, T b, T offset) 
   where T: Number { // <- T can be any integer or floating point type 
     a = Math.Abs(a);
     ....

Unfortunately, .Net doesn't provide such an interface and so you have to implement overload versions of IsEqual:

  bool IsEqual(this Double a, Double b, Double offset) {
    return (Math.Abs(a - b) < offset);
  }

  bool IsEqual(this Single a, Single b, Single offset) {
    return (Math.Abs(a - b) < offset); 
  }

  bool IsEqual(this long a, long b, long offset) {
    return (Math.Abs(a - b) < offset);
  }

  bool IsEqual(this int a, int b, int offset) {
    return (Math.Abs(a - b) < offset);
  }
  ...
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215