Simple Extension Method to Evaluate Listings For a Match
February 4th, 2009
I’m currently dealing with a system that switches between different states, which require evaluations that look similar to the snippet below:
//check status flags TestStatus status = GetStatus(); if (status == TestStatus.Preparing || status == TestStatus.Running || status == TestStatus.PostDelay) { ... }
Given the fact that I’m having lots of states, I had to produce pretty nasty code, so I wrote that handy little extension method that takes care of the issue once and for all:
Edit (2009.02.08): Returning false for null values which allows to submit null references without exception.
/// <summary> /// Checks a list of candidates for equality to a given /// reference value. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="value">The evaluated value.</param> /// <param name="candidates">A liste of possible values that are /// regarded valid.</param> /// <returns>True if one of the submitted <paramref name="candidates"/> /// matches the evaluated value. If the <paramref name="candidates"/> /// parameter itself is null, too, the method returns false as well, /// which allows to check with null values, too.</returns> /// <exception cref="ArgumentNullException">If <paramref name="candidates"/> /// is a null reference.</exception> public static bool Is<T>(this T value, params T[] candidates) { if (candidates == null) return false; foreach (var t in candidates) { if (value.Equals(t)) return true; } return false; }
Using this “Is” extension, I can now write the above code like this:
if (status.Is(TestStatus.Preparing, TestStatus.Running, TestStatus.PostDelay)
{
...
}
Of course, this is not limited to Enums but works with everything that supports the Equals operator:
string name = ... if (name.Is("foo", "bar")) { //foobar! }
Looks like this is one of the few instances where VB.NET outshines C# with syntactic sugar.
It appears that you are implementing something like VB.NET’s Select…Case statement:
http://msdn.microsoft.com/en-us/library/cy37t14y.aspx
I am a big fan of the ‘To’ conjunction to succinctly specify ranges. But, listing multiple cases with commas is nice too.
I do not know C# very well but it appears that neither of those two features are available:
http://msdn.microsoft.com/en-us/library/06tc147t.aspx
Way to fill the gap!
Eddie,
I’d say SELECT/CASE and SWITCH are functionally equivalent, aren’t they? Here’s a translation of if/else into switch. As you can see, neither is exactly short 😉
if (status == 1)
foo();
else if (status == 2 || status == 4)
bar();
else
foobar();
switch(status)
{
case 1:
foo();
break;
case 2:
case 4:
bar();
default:
foobar();
break;
}