This is called null coalescing, and there is a built in operator to do it:
int myValue = record.myField ?? 0
Pregunta
I wrote this trivial utility function:
public static T isNull<T>(T? v, T d)
{
return v == null ? d : v.Value;
}
the purpose is to avoid annoying task like check for a member to be null, very common in reading a linq recordset. The problem is that it's throwing this error:
The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable< T>'
The error seems legit, anyway I wish I can do something like this:
int? myField = record.myField;
int myValue = isNull(myField, 0);
instead of:
int? myField = record.myField;
int myValue = myField == null ? 0 : myField.Value;
I feel like I'm missing some c# basic knowledge. Does exist a way to accomplish my task?
Solución 2
This is called null coalescing, and there is a built in operator to do it:
int myValue = record.myField ?? 0
Otros consejos
Generic constraints can be used on generic functions to limit the types that are permitted to be used to certain subsets, and this opens up possibilities for how you might use those types inside your method or class.
In this case, you can apply a constraint to T
that limits it to a struct
to resolve your specific compiler error.
public static T IsNull<T>(T? v, T d) where T : struct
{
return v == null ? d : v.Value;
}
However, another answer does correctly point out that you could opt to use the null coalescing operator ??
in this particular situation.
While the other answers are good, presumably you'd like to write your method so it would work with both reference and value types. You can accomplish that by having two overloads, both with generic constraints.
public static T IsNull<T>(T v, T d) where T : class
{
return v ?? d;
}
public static T IsNull<T>(T? v, T d) where T : struct
{
return v.HasValue ? v.Value : d;
}
NOTE: Calling IsNull
with a value type other than Nullable<T>
will still not compile. e.g.
string myString = ...
Console.WriteLine(IsNull(myString, "foo")) // works
object myObject = ...
Console.WriteLine(IsNull(myMyObject, new object())) // works
DateTime? myDateTime = ...
Console.WriteLine(IsNull(myDateTme, DateTme.Now)) // works
int? myInt1 = ...
Console.WriteLine(IsNull(myInt1, DateTme.Now)) // works
int myInt2 = ...
Console.WriteLine(IsNull(myInt2, DateTme.Now)) // <-- compiler error