Bunion Cimurro
Bunion Cimurro

Reputation: 43

Generic cast method returning base type (struct)

I'd like to write a method that cast a value (object) into a basic type (like string, int, double, etc..). I use this method in a routine that maps DataRows on objects.

I wrote this:

public static T CastObjectToBasicType<T>(DataRow row, string column)
    where T : struct
{
    object cellValue = row[column];

    if (typeof(T) == typeof(string))
        return ToString(cellValue);

    if (typeof(T) == typeof(int) || typeof(T) == typeof(int?))
        return ToInt(cellValue);

    if (typeof(T) == typeof(bool) || typeof(T) == typeof(bool?))
        return ToBool(cellValue);

    if (typeof(T) == typeof(double) || typeof(T) == typeof(double?))
        return ToDouble(cellValue);

    if (typeof(T) == typeof(decimal) || typeof(T) == typeof(decimal?))
        return ToDecimal(cellValue);

    if (typeof(T) == typeof(DateTime) || typeof(T) == typeof(DateTime?))
        return ToDateTime(cellValue) ;

     throw new ArgumentException("T not supported");
}

where methods like ToString, ToBool, ToDouble, etc... are simple methods that convert input into the desidered type.

The code above doesn't compile; the problem is that I'm not able to cast the result into type T, because T is a struct and i cant use (for exaple)

return ToDouble(obj) as T;

neither

return (T) ToDouble(obj);

If i replace the clause

where T : struct

with

where T : class

then I'm not able to call the method using int, bool, double, etc... as T because them are not classes.

I don't know if there is a way to accomplish this; the alternative is to call directly the simple methods like ToBool, ToInt, etc... without passing from a generic method, but I prefer to have a single cast method.

Is there anything I can do? Any help would be appreciated, also alternatives.

Thanks in advance.

Upvotes: 0

Views: 2875

Answers (2)

dcastro
dcastro

Reputation: 68660

That's because, as far as the compiler knows, there's no possible conversion between T and, for example, DateTime.

Try upcasting DateTime to the only ancestor DateTime and T have in common - object - and then downcasting back to T.

return (T) (object) ToDouble(obj);

Upvotes: 5

Ronan Thibaudau
Ronan Thibaudau

Reputation: 3603

You don't need to specify a where T clause unless you actually want to limit to something (interface , class, struct etc). Here you don't, so just remove the where clause

Upvotes: 0

Related Questions