Reputation: 43
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
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
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