views:

81

answers:

1

This question got me thinking on how one could approach writing a method that would need to contain a variable list of type parameters.

One approach would be to accept params Type[] as part of the arguments, such as:

public static bool IsOneOf(this object obj, params Type[] types)
{
    return types.Contains(obj.GetType());
}

However, the use is a little verbose (e.g. obj.IsOneOf(typeof(int), typeof(bool), typeof(double))) and I am wondering about alternative approaches to defining one method taking an arbitrary amount of generic arguments. Something akin to:

public static bool IsOneOf<params TArgs[]>(this object obj)
{
    // use TArgs here
}

One solution to this would be to use the 4.0 BCL's Tuple classes (it defines a common interface ITuple as well as Tuple<T1>, Tuple<T1, T2>, etc) to define something like the following:

public static bool IsOneOf<TTypes>(this object obj) where TTypes : ITuple
{
    Type tupleType = typeof(TTypes);
    return tupleType.GetGenericArguments().Contains(obj.GetType());
}

It could then be used like this:

if (obj.IsOneOf<Tuple<int, bool, decimal>>()) { ... }

Are there performance considerations here, or are there an alternative methods to achieve this syntax?

+1  A: 

You could possible squeeze out a little extra speed by unrolling the loop into special cases for each "arity":

static bool IsOneOf<T1>(object o)
{
    return (o.GetType() == typeof (T1));
}

static bool IsOneOf<T1, T2>(object o)
{
    return (o.GetType() == typeof(T1)) ||
           (o.GetType() == typeof(T2));
}

static bool IsOneOf<T1, T2, T3>(object o)
{
    return (o.GetType() == typeof(T1)) ||
           (o.GetType() == typeof(T2)) ||
           (o.GetType() == typeof(T3));
}

And so on.

But then, how often do you need to know if an object is one or the other of a pair of unrelated types? Let alone three or more. Seems quite an obscure need to me.

Daniel Earwicker