7

I have a line of code that looks like this:

if (obj is byte || obj is int || obj is long || obj is decimal || obj is double || obj is float)

Is it possible to write something more elegant than this? Something like:

if (obj is byte, int, long)

I know that my example isn't possible, but is there a way to make this look "cleaner"?

Jon Tackabury
  • 47,710
  • 52
  • 130
  • 168

7 Answers7

27

You could write an extension method on object to give you syntax like:

if (obj.Is<byte, int, long>()) { ... }

Something like this (use multiple versions for fewer or more generic arguments:

public static bool Is<T1, T2, T3>(this object o)
{
    return o is T1 || o is T2 || o is T3;
}
Jason
  • 28,040
  • 10
  • 64
  • 64
  • 4
    I would name the method IsOneOf, but this is a very concise syntax indeed. – jeroenh Jul 28 '09 at 14:23
  • 1
    shame you can't use something like params for generic parameters – Matthew Whited Jul 28 '09 at 15:07
  • @Matthew, I wonder if one could define `interface ITuple` and then subclass it with a variety of tuple generic classes (`Tuple : ITuple`, `Tuple : ITuple`, etc). Then redo the extension method as `Is where TTuple : ITuple`.. Then unwrap the generic type arguments inside of the method.. This would give `params`-like generic argument functionality... – Jason Jul 28 '09 at 16:00
12

Only:

static readonly HashSet<Type> types = new HashSet<Type> 
    { typeof(byte), typeof(int), typeof(long) etc };

...

if (types.Contains(obj.GetType())
{
}

Or use obj.GetType().GetTypeCode().

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
8

I would throw it into a method to simplify it a bit:

private static bool ObjIsNumber(object obj)
{
    return  (obj is byte || obj is int || obj is long || 
             obj is decimal || obj is double || obj is float);
}
jjnguy
  • 136,852
  • 53
  • 295
  • 323
3

Why don't you do this?

bool IsRequestedType(object obj)
{
    if (obj is byte || obj is int || obj is long || obj is decimal || obj is double || obj is float)
         return true;
    return false;
}

Or you might be able to get away with

obj is IComparable
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
1

That looks fine to me - nice and clear.

Justin
  • 84,773
  • 49
  • 224
  • 367
1

Create a helper function to put your test in.

Something like

public static Boolean IsNumeric(Object myObject) {
    return (obj is byte || obj is int || obj is long || obj is decimal || obj is double|| obj is float);
}
jjnguy
  • 136,852
  • 53
  • 295
  • 323
NotMe
  • 87,343
  • 27
  • 171
  • 245
1
public static bool IsOneOf(object o, params Type[] types)
{
    foreach(Type t in types)
    {
        if(o.GetType() == t) return true;   
    }

    return false;
}

long l = 10;
double d = 10;
string s = "blah";

Console.WriteLine(IsOneOf(l, typeof(long), typeof(double))); // true
Console.WriteLine(IsOneOf(d, typeof(long), typeof(double))); // true
Console.WriteLine(IsOneOf(s, typeof(long), typeof(double))); // false
Chris Doggett
  • 19,959
  • 4
  • 61
  • 86