I want to do something like this :
myYear = record.GetValueOrNull<int?>("myYear"),
Notice the nullable type as the generic parameter.
Since the GetValueOrNull
function could return null my first attempt was this:
public static T GetValueOrNull<T>(this DbDataRecord reader, string columnName) where T : class { object columnValue = reader[columnName]; if (!(columnValue is DBNull)) { return (T)columnValue; } return null; }
But the error I'm getting now is:
The type 'int?' must be a reference type in order to use it as parameter 'T' in the generic type or method
Right! Nullable<int>
is a struct
! So I tried changing the class constraint to a struct
constraint (and as a side effect can't return null
any more):
public static T GetValueOrNull<T>(this DbDataRecord reader, string columnName) where T : struct
Now the assignment:
myYear = record.GetValueOrNull<int?>("myYear");
Gives the following error:
The type 'int?' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method
Is specifying a nullable type as a generic parameter at all possible?
This means that you can put any object in a collection because all classes in the C# programming language extend from the object base class. Also, we cannot simply return null from a generic method like in normal method.
You typically use a nullable value type when you need to represent the undefined value of an underlying value type. For example, a Boolean, or bool , variable can only be either true or false .
Nullable reference types aren't new class types, but rather annotations on existing reference types. The compiler uses those annotations to help you find potential null reference errors in your code. There's no runtime difference between a non-nullable reference type and a nullable reference type.
C# 2.0 introduced nullable types that allow you to assign null to value type variables. You can declare nullable types using Nullable<t> where T is a type. Nullable<int> i = null; A nullable type can represent the correct range of values for its underlying value type, plus an additional null value.
Change the return type to Nullable<T>
, and call the method with the non nullable parameter
static void Main(string[] args) { int? i = GetValueOrNull<int>(null, string.Empty); } public static Nullable<T> GetValueOrNull<T>(DbDataRecord reader, string columnName) where T : struct { object columnValue = reader[columnName]; if (!(columnValue is DBNull)) return (T)columnValue; return null; }
public static T GetValueOrDefault<T>(this IDataRecord rdr, int index) { object val = rdr[index]; if (!(val is DBNull)) return (T)val; return default(T); }
Just use it like this:
decimal? Quantity = rdr.GetValueOrDefault<decimal?>(1); string Unit = rdr.GetValueOrDefault<string>(2);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With