10 utilities C# Developers should know, part one

One of the things I like most about C# is that features like generics and extension methods make it easy to build utility methods to fill most gaps in the language and .NET base class libraries. Here are a few of my favorites. As a note, the implementations shown below are missing things like argument validation in favor of brevity. For more complete implementations, check out https://gist.github.com/madelson/9177264.


Throw.If
Assertions, argument checks, and other validity tests are a vital part of programming, but they can be surprisingly painful in C#. Debug.Assert() comes out of the box, but only works in a DEBUG build and doesn’t let you specify the type of exception to be thrown. Meanwhile, spending 3 lines per check on if (…) { throw new … } cheap MLB jerseys with Allman braces gets cumbersome very quickly. Throw.If is a simple method that makes it easy to do 1-line checks while still maintaining the flexibility of using different exception types:

public static class Throw<TException> where TException : Exception
{
    public static void If(bool condition, string message) 
    {
        if (condition)
        {
            throw (TException)Activator.CreateInstance(typeof(TException), 
                <a href="http://www.lemece.com/12.html">top</a>                                          message);
        }
    }
}

Why is the generic parameter on the type and not the method? It could clearly go in either place, but I chose to place it on the type since it leads to the most natural English reading of the code “Throw ArgumentException If a == null” instead of “Throw If ArgumentException a == null”.

NullSafe
Null values are a frustrating fact of life in C#, and checking for them frequently breaks the natural cadence of coding. You just want to write foo.GetBar().Baz.SomeMethod(), but checking for null at each step along the way turns this concise chain of calls into an ugly sequence of ifs and curly braces. The NullSafe function allows these checks to happen more or less inline, maintaining the structure of the code while dodging NullReferenceExceptions:

public static TResult NullSafe&lt;TObj, TResult&gt;(
    this TObj obj, 
    Func&lt;TObj, TResult&gt; func, 
    TResult ifNullReturn = default(TResult))
{
    return obj != null ? func(obj) : ifNullReturn;
}

With this extension, the above chain might be re-written as:

foo.NullSafe(f =&gt; f.GetBar())
   .NullSafe(b =&gt; b.Baz)
   .NullSafe(b =&gt; b.SomeMethod(), ifNullReturn: &quot;whatever you would return in the null case&quot;);

To support invoking void methods at the end of the chain, just add an overload that takes Action instead of Func.

Capped
For some reason, I always find Max() and Min() to be confusing when trying to bound values, likely because you need Min() to set an upper bound and Max() to set a lower bound. Hence, I use a Capped() extension method to handle the common case of bounding a value within a range:

public static T Capped&lt;T&gt;(this T @this, T? min = null, T? max = null)
    where T : struct, IComparable&lt;T&gt;
{
    return min.HasValue &amp;&amp; @this.CompareTo(min.Value) &lt; 0 ? min.Value
        : max.HasValue &amp;&amp; @this.CompareTo(max.Value) &gt; 0 ? max.Value
        : @this;
}

For example, bounding an integer to between 1 and 10 becomes:

var bound = value.Capped(min: 1, max: 10);

Instead of the (in my opinion) far-less-readable:

var bound =  <a href="http://gwinnettstateofthecounty.com/photos/">Photos</a>  Math.Max(1, Math.Min(value, 10));

Traverse.Along
I’ve generally found that the LinkedList data structure available in the BCL rarely comes up in everyday coding; in nearly all cases List or IEnumerable is preferable. That said, code I work with is often full of “natural” linked lists, such as the BaseType property on Q2, Type or the InnerException property on Exception. This handy method, which I adapted from some code I saw while browsing the Autofac codebase, makes it easy to work with these structures as IEnumerables without having to go through a cumbersome conversion loop each time:

public static class Traverse
{
    public static IEnumerable&lt;T&gt; Along&lt;T&gt;(T node, Func&lt;T, T&gt; next) 
            where T : class
    {
        for (var current = node; current != null; current = next(current))
        {
            yield return current;
        }
    }
}

With Along(), finding a (possible) inner SqlException from an Exception becomes:

catch (Exception ex)
{
    var sqlException = Traverse.Along(ex, e =&gt; e.InnerException)
                               .OfType&lt;SqlException&gt;()
                               .FirstOrDefault();
}

Given this structure, it’s easy to imagine similar utilities for doing depth-first, breadth-first, and other traversals of arbitrary tree-like data structures.

As
This method is essentially a type-safe, inline cast. Just looking at the implementation, it seems completely pointless:

public static T As&lt;T&gt;(this T @this) { return @this; }

However, there are a several places where this method can wholesale MLB jerseys come in handy. One is type
inference. For example, you may have run into this problem:

// the compiler complains that &#039;Type of conditional expression cannot be 
// determined because there is no implicit conversion between 
// &#039;System.Collections.Generic.List&lt;int&gt;&#039; and &#039;System.Collections.Generic.HashSet&lt;int&gt;&#039;&#039;
ICollection&lt;int&gt; collection = someCondition ? new List&lt;int&gt;() 
                                <a href="http://www.codeducky.org/hello-world/">Hello</a>               : new HashSet&lt;int&gt;();

The common fix is to add a cast:

ICollection&lt;int&gt; collection = someCondition 
    ? (ICollection&lt;int&gt;)new List&lt;int&gt;() 
    : new HashSet&lt;int&gt;();

However, this is ugly because we are using a cast for what is really a type-safe operation: we know that the cast is guaranteed to succeed. However, since cheap MLB jerseys there’s no way to specify that, someone could swap out “new List()” for “new object()” and things would still compile: we’ve essentially given up some type-safety!

As() fixes this for us:

// compiles
ICollection&lt;int&gt; collection = someCondition 
    ? new List&lt;int&gt;().As&lt;ICollection&lt;int&gt;&gt;() 
    : new HashSet&lt;int&gt;();

// does not compile (since the &quot;this&quot; parameter of As must be of type T... 
// in this case ICollection&lt;int&gt;)
ICollection&lt;int&gt; collection = someCondition 
    ? new object().As&lt;ICollection&lt;int&gt;&gt;() 
    : new HashSet&lt;int&gt;();

Another common use is when dealing with explicitly implemented interfaces. For example, let’s say you wanted to access the ICollection.SyncRoot property on a List:

// doesn&#039;t compile: SyncRoot is explicitly implemented and therefore private
var syncRoot = new List&lt;int&gt;().SyncRoot;

// ugly and not type-safe
var syncRoot = ((ICollection)new List&lt;int&gt;()).SyncRoot;

// type-safe, but takes 2 lines and isn&#039;t chainable
ICollection collection = new List&lt;int&gt;();
var syncRoot = collection.SyncRoot

// type-safe, 1 line!
var syncRoot = new List&lt;int&gt;().As&lt;ICollection&gt;().SyncRoot;
Mike Adelson

Mike Adelson

Software Engineer at Applied Predictive Technologies
I'm a software engineer at Applied Predictive Technologies in Washington D. C., where I work on "big data" analytics and.NET web development. In my spare time, I enjoy reading, working on various side projects, and answering questions on StackOverflow.
Mike Adelson

Latest posts by Mike Adelson (see all)

Leave a Reply