Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if value is 0 with extension method

Tags:

c#

I have an extension method which looks like

public static T ThrowIfObjectIsNull<T>(this T argument) where T : class
{
  if (argument == null)
      throw new ArgumentNullException(nameof(argument));

   return argument;
}

This basically check if the object that's being passed isn't null. What I am trying to do is create another extension method where the int value which is being passed in isn't 0. So I have gone ahead and created:

public static T ThrowIfZero<T>(this T argument) where T : struct
{
   if (argument == 0)
     throw new ArgumentOutOfRangeException("some error here");

   return argument;
}

Of course the above does not compile suggesting the error:

Error CS0019 Operator '==' cannot be applied to operands of type 'T' and 'int'

Can someone point me to the right direction on how I would check if the argument value isn't 0?

like image 650
Izzy Avatar asked May 16 '18 13:05

Izzy


4 Answers

You could simply use Equals:

public static T ThrowIfZero<T>(this T argument) where T : struct
{
    if (argument.Equals(0))
        throw new ArgumentOutOfRangeException("some error here");

    return argument;
}

But that will not really work well if the argument is for example a decimal 0.0m which is not equal to the integer 0 as Peter has commented correctly.

So if you want a version that works for any number you could use this approach:

public static T ThrowIfZero<T>(this T argument) where T : struct
{
    bool isZero = Decimal.Compare(0.0m, Convert.ToDecimal(argument)) == 0;
    if (isZero)
        throw new ArgumentOutOfRangeException("some error here");

    return argument;
}
like image 162
Tim Schmelter Avatar answered Oct 06 '22 14:10

Tim Schmelter


You can use EqualityComparer as well.

public static T ThrowIfZero<T>(this T argument) where T : struct
{   
     if (EqualityComparer<T>.Default.Equals(argument, default(T)))   
        throw new ArgumentOutOfRangeException("some error here");

     return argument;
}

You can refer answer of this post (credit should go to @Mehrdad).

like image 30
par Avatar answered Oct 06 '22 15:10

par


It doesn’t look like you need generics at all. If the variable is just an int as you suggest, just use:

public static int ThrowIfZero(this int argument)
{
    if (argument == 0)
    {
        throw new ArgumentOutOfRangeException("some error here");
    }

    return argument;
}
like image 4
Callum Watkins Avatar answered Oct 06 '22 14:10

Callum Watkins


int, decimal etc. implement IComparable so something like this also works:

public static T ThrowIfZero<T>(this T argument) 
    where T : struct, IComparable
{
   if (argument.CompareTo(default(T)) == 0)
     throw new ArgumentOutOfRangeException("some error here");

   return argument;
}
like image 1
BartoszKP Avatar answered Oct 06 '22 14:10

BartoszKP