К сожалению, вы не сможете получить возвращаемый тип Nullable И поддержку ссылочных типов с помощью обобщенных типов, если только вы не укажете, что хотите вернуть Nullable при вызове
public static T Get<T>(this DataRow row, string field)
{
if (row.IsNull(field))
return default(T);
else
return (T)row[field];
}
и когда вы звоните
var id = dr.Get<int?>("user_id");
Я не проверял это, просто бросил здесь. Дайте ему шанс.
EDIT:
В качестве альтернативы, если вы действительно хотите преобразовать типы значений в обнуляемые значения и при этом иметь возможность поддерживать ссылочные типы, что-то подобное может сработать
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];
}
}
Тем не менее, это потребовало бы применения при каждом использовании
var id = dr.Get<string>("username") as string;
var id = (int?)dr.Get<int>("user_id");
Это, однако, не будет столь же эффективным, как просто принятие обнуляемого типа в параметрах универсального типа.