Unfortunately, you're not going to be able to get the Nullable return type AND support for reference types by using generics, unless you specify that you want a Nullable returned when you make the call
public static T Get<T>(this DataRow row, string field)
{
if (row.IsNull(field))
return default(T);
else
return (T)row[field];
}
and when you call
var id = dr.Get<int?>("user_id");
I didn't test this, just tossed it up here. Give it a shot.
EDIT:
Alternatively, if you really wanted to convert the value types into nullables and still be able to support reference types something like this might work
public static object GetDr<T>(this DataRow row, string field)
{
// might want to throw some type checking to make
// sure row[field] is the same type as T
if (typeof(T).IsValueType)
{
Type nullableType = typeof(Nullable<>).MakeGenericType(typeof(T));
if (row.IsNull(field))
return Activator.CreateInstance(nullableType);
else
return Activator.CreateInstance(nullableType, new[] { row[field] });
}
else
{
return row[field];
}
}
However, it'd require a cast on every usage
var id = dr.Get<string>("username") as string;
var id = (int?)dr.Get<int>("user_id");
This is, however, not going to be nearly as efficient as just accepting the nullable type in the generic type parameters.