4

I have an extension method that accepts a parameter T. This parameter is a numeric type, one of the following: byte, short, int and long.

I need to check if T equals to 0. How is it possible to do that?

public static void WriteFlaggedValue<T>(this OutPacket outPacket, uint flag, T value, ref uint outputFlag) where T : struct,
      IComparable,
      IComparable<T>,
      IConvertible,
      IEquatable<T>,
      IFormattable
    {
        if (value == 0)
        {

        }

    }
Gilbert Williams
  • 970
  • 2
  • 10
  • 24
  • It seems like you'll want [this](http://stackoverflow.com/a/5182747/2150749) check. – Jashaszun Jul 15 '15 at 17:17
  • I dont think there is any built in support to enforce T being numeric, which makes this possibly a bad idea. but couldn't you just do `if(value ==(T)0)`? If you only have 4 possible types, I would probably recommend just making an overload for each of those types. – pquest Jul 15 '15 at 17:17
  • 3
    How you're supposed to enforce that `T` is `byte, short, int and long`? Generics doesn't seem the correct approach. Maybe overloading suits better – Claudio Redi Jul 15 '15 at 17:18
  • you could use typeof() and check it for the numeric types. Then Throw an exception if it is not what you want. – tdbeckett Jul 15 '15 at 17:19
  • @tdbeckett while this is true, I still think this approach is rather sloppy compared to 4 overloads. With that method, you end up with a runtime error rather than a compile-time error. – pquest Jul 15 '15 at 17:20
  • You might want to look at this [post](http://stackoverflow.com/questions/32664/is-there-a-constraint-that-restricts-my-generic-method-to-numeric-types). In particular, Sergey Shandar's and Jeroen Vannevel's answers provide some nice ways to make methods work with any numeric type. – Fernando Matsumoto Jul 15 '15 at 17:51

4 Answers4

5

You can use the EqualityComparer class like this

if(EqualityComparer<T>.Default.Equals(value, default(T))
{
}

Stackoverflow: EqualityComparer<T>.Default vs. T.Equals

MSDN: EqualityComparer.Default

Community
  • 1
  • 1
Bidou
  • 7,378
  • 9
  • 47
  • 70
1

One option you have to do this, is using the compareTo method of the IComparable interface, with the default type value...

If they are equals it will return zero as is specified here.

The condition will look as follows:

if (value.CompareTo(default(T)) == 0)

Used in your method:

public static void WriteFlaggedValue<T>(this OutPacket outPacket, uint flag, T value, ref uint outputFlag) where T : struct,
      IComparable,
      IComparable<T>,
      IConvertible,
      IEquatable<T>,
      IFormattable
    {
        if (value.CompareTo(default(T)) == 0)
        {

        }

    }

If value can be null then you have to handle it.

gastonmancini
  • 1,102
  • 8
  • 19
1

Since no one has said it yet, why not simply take advantage of the very straight-forward Equals(T other) function that comes for free with the IEquatable<T> interface:

if (value.Equals(default(T)))
{
    // ...
}

A note about the use of the default keyword in case OP is wondering how this works:

The documentation found here, says the following (emphasis mine):

The solution is to use the default keyword, which will return null for reference types and zero for numeric value types.


It should also be mentioned that just because you are restricting T to be a struct does not mean that you are guaranteed that T will always be numeric. For instance, your method could accept a DateTime as the generic type. Maybe you already know that and are ok with that.

More on that here: What is the “base class” for C# numeric value types?

Community
  • 1
  • 1
sstan
  • 35,425
  • 6
  • 48
  • 66
0

How abouts:

private T _minimumValue = default(T)

public bool IsEqualsZero(T value) 
{
    return (value.CompareTo(_minimumValue) == 0);
}

As suggested in This Answer

Community
  • 1
  • 1
Rishiv93
  • 55
  • 14