So, this blogging stuff is hard. Well, to be more precise, finding the time having the discipline during my free time to sit down and write something every day is hard. I like to think of it less as laziness and more as me not responding when there’s no immediate challenge, but I’m admittedly biased.
Anyway, while my commentary on buying e-books from Barnes and Noble’s Nook store languishes away as a half-written draft, I’ll throw another helpful code snippet up here (even though it’s an old one that I’m sure many of you have already figured out) just so I can check “write something for teh blog” off my to-do list. What? That’s how it’s spelled on the to-do list. I’m just being faithful here.
.NET Nullables rock
The .NET Nullable struct is pretty cool, finally solving the long-standing “impedence mismatch” between three-value logic and how things work where most of us sane people live. Nullable let us distinguish between “no value” and “the default value” when we needed to without resorting to insane workarounds, unenforceable conventions or blatant hacks to do so.
The trouble is, there are times when the cure is worse than the disease. Use nullable types for any length of time at all and you’ll find yourself writing code like this everywhere:
Nullable b = GetSomeDatabaseValue();
bool theValue = false;
if(b.HasValue)
{
theValue = b.Value;
}
DoSomethingWith(theValue);
Because, if you blindly go calling Value, Nullable will throw a nice exception into your lap. The clever developer will quickly decide to “tern that mother out” and wind up with something at least a little more copy-paste friendly:
Nullable b = GetSomeDatabaseValue(); DoSomethingWith((b.HasValue ? b.Value : false));
This is better, but it still counts as repeating yourself since you’re going to have to repeat that ternary logic everywhere. This approach also has further disadvantages that ternary expressions are hard for some people to grasp, and it’s just a difficult coding standard to enforce.
You do want a standard though, that your whole team follows. I’ve personally seen code bases where the team apparently left the standard up to the individual developer, and this was one developer’s chosen method:
Nullable b = GetSomeDatabaseValue();
try
{
DoSomethingWith(b.Value);
}
catch
{
//pass
}
The simple truth is, sometimes we just don’t care to distinguish between default value and null, and want to be able to safely compress that triple-value logic down into the simple boolean logic we’re all used to dealing with. Extension methods to the rescue:
/// <summary>
/// Retrieves the value of any nullable type, returning the default if it is null
/// (for numeric types this is zero).
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="nullable"></param>
/// <returns></returns>
///
/// <example>
/// int? foo = null;
/// Console.WriteLine(foo.SafeValue()); // writes 0
/// foo = 42
/// Console.WriteLine(foo.SafeValue()); // writes 42
/// </example>
///
public static T SafeValue<T>(this Nullable<T> nullable )
where T : struct
{
if (nullable.HasValue)
return nullable.Value;
else
return default(T);
}
The SafeValue implementation above is probably a little naive, but it should be good for 90% of the cases where you’ll want to use it. It lets you turn the “use its value if it has one, otherwise use the default” logic into a one-liner:
Nullable b = GetSomeDatabaseValue(); DoSomethingWith(b.SafeValue());
Comments are closed.