Collection of small but useful extensions methods #1

I’ve done a few posts on some useful extension methods before, but there’s also a bunch of smaller extension methods I wanted to share that didn’t each warrant their own post – so below are some of the small but useful methods I’ve used in the past!

IDictionary – GetValueOrThrow

Dictionaries are great in .NET – they allow super fast key lookups to retrieve a paired value. Sometimes, you’ll try to retrieve the value for a key that doesn’t exist in the dictionary, and you’ll be met with a very generic ‘KeyNotFoundException’. I’ve always wished this would actually include the key that the code attempted to lookup in the error message, as to say it would aid debugging would be an understatement! So I created the below extension method which does include the key in the error message (just be sure that including the key isn’t going to be a security risk if a user sees it!)

public static U GetValueOrThrow<T, U>(this Dictionary<T, U> dict, T key, U defaultValue = default(U))
{
    U value;
    if (!dict.TryGetValue(key, out value))
        throw new KeyNotFoundException($"Cannot find key {key}");

    return value;
}

IDictionary – GetValueOrDefault

As a natural counterpart to the first extension method, this one will return a default value if the key doesn’t exist. Very useful, and it avoids having to constantly use awful ‘out’ parameters. Note that if you don’t pass in a default value, the value will simply be the default value of the type – 0 for int, null for reference types.

public static U GetValueOrDefault<T, U>(this Dictionary<T, U> dict, T key,U defaultValue = default(U))
{
    U value;
    if (!dict.TryGetValue(key, out value))
        return defaultValue;

    return value;
}

String – SafeSubstring

How many times have you had to had to write this boilerplate code when trying to extract a substring?

var extract = input.Length >= 20 ? input.Substring(0,20) : input;

With the below extension method, this becomes a thing of the past!

public static string SafeSubstring(this string input, int start, int length)
{
    if (input == null)
        throw new ArgumentNullException(nameof(input));
    if (input.Length >= (start+ length))
        return input.Substring(start, length);
    
    return input.Length > start ? input.Substring(start) : string.Empty;
}

ASP.NET Control – FindControlOrThrow<T>

This one is specific to ASP.NET WebForms (I shudder when I type that), and helps reduce a bit of the boiler plate code and it reduces the chances of the dreaded ‘Object reference not set to an instance of an object’ error by throwing a meaningful exception if the control could not be found. It also reduces the need to cast the return value, as the type is passed in as a generic argument

public static T FindControlOrThrow<T>(this Control parentControl, string name) where T : Control
{
    if (parentControl == null)
        throw new ArgumentNullException(nameof(parentControl));

    Control controlGeneric = parentControl.FindControl(name);
    if (controlGeneric == null)
        throw new Exception($"Cannot find control with name '{name}' in parent '{parentControl.ID}'");

    var control = controlGeneric as T;
    if (control == null)
        throw new Exception($"Cannot convert control '{name}' of type {controlGeneric.GetType().Name} to type {typeof(T).Name}");

    return control;
}