This is pure curiosity/challenge, no practical importance at all. So I'm not looking for alternate solutions that get the job done.
From this question Most efficient way to check for DBNull and then assign to a variable? I found this answer which looks like:
oSomeObject.IntMemeber = oRow["Value"] as int? ?? iDefault;
oSomeObject.StringMember = oRow["Name"] as string ?? sDefault;
Can I move the above expressions to one generic function (or two, or more) so that it accepts both int?
and string
as well and that I can call it like:
oSomeObject.IntMemeber = oRow.Read<int?>("Value", 0); //iDefault is now 0
//or
oSomeObject.IntMemeber = oRow.Read<int>("Value"); //iDefault is now default(int)
//and
oSomeObject.StringMember = oRow.Read<string>("Name"); //sDefault is now default(string)
Requirements:
1) I need an option to specify a default value in case of DBNull
s. I also need an option to return default(T)
in case I dont specify a default value. So this wont work:
public static T Read<T>(this IDataRecord dr, string field, T defaultValue) where T : class
{
return dr[field] as T ?? defaultValue;
}
public static T? Read<T>(this IDataRecord dr, string field, T? defaultValue) where T : struct
{
return dr[field] as T? ?? defaultValue;
}
because I cant call oSomeObject.StringMemeber = oRow.Read<string>("Name")
It need not be optional parameter, it can even be an overload:
public static T Read<T>(this IDataRecord dr, string field) where T : class
{
return dr[field] as T ?? default(T);
}
public static T? Read<T>(this IDataRecord dr, string field) where T : struct
{
return dr[field] as T? ?? default(T?);
}
public static T Read<T>(this IDataRecord dr, string field, T defaultValue) where T : class
{
return dr[field] as T ?? defaultValue;
}
public static T? Read<T>(this IDataRecord dr, string field, T? defaultValue) where T : struct
{
return dr[field] as T? ?? defaultValue;
}
This wont compile, since method 1 and 2 have just the same signature.
2) Generic functions (in case of overloads) should have the same name.
3) as
keyword must be used check and cast type. As I stated previously I'm not really looking to solutions to read from IDataRecord
or enhance performance or something.
There are similar questions
C# generic class using reference types and nullable value types
Is creating a C# generic method that accepts (nullable) value type and reference type possible?
Can a Generic Method handle both Reference and Nullable Value types?
But this is very specific to as
keyword. So the answers there are not applicable.
Addendum: I know there won't be one single solution to this. I will accept which is most elegant alternative.