SQL Like 'In' Function For .NET

SQL has a wonderful terse and natural syntax for checking if an item is inside of a collection by using the IN keyword. Which can be expressed like this:

expression IN (value_1, value_2, .... value_n)

In .NET, we can preform the same operation with .Contains() method on any enumerable collection which:

Determines whether a sequence contains a specified element

Beginning with VB 2010, we can even do this on the fly by using the Collection Initializers.

For example, to check whether a variable called personName was either "Sally" or "Jenny", we could use the following expression:

{"Sally","Jenny"}.Contains(personName)

However, I think this syntax leaves something to be desired. The verbiage is all wrong. I don’t really care if a collection contains some item. I care if an item is in a collection. Of course, logically, this is performing the same operation, but I want the personName variable to be in the drivers seat. I want personName to be the subject that is verbing against the other items.

For a bit of syntactic sugar, we can add a generic extension method to take in an ParamArray and check if the extended element falls inside that array.

Here’s the In method:

Note: In needs to be inside of square brackets because it is a Protected Keyword.

Visual Basic

''' <summary>
''' Determines if the Item is contained within the listed array
''' </summary>
''' <typeparam name="T">The type of object</typeparam>
''' <param name="item">The calling item</param>
''' <param name="range">An array or comma separated list of the items to check against the calling</param>
''' <returns>True if item is found in list</returns>
''' <remarks>Provides syntatic sugar by reordering the subject of the IEnumerable.Contains method</remarks>
<Extension()>
Public Function [In](Of T)(ByVal item As T, ByVal ParamArray range() As T) As Boolean
    Return range.Cast(Of T).Contains(item)
End Function

C Sharp

public static class Extensions
{
    /// <summary>
    /// Determines if the Item is contained within the listed array
    /// </summary>
    /// <typeparam name="T">The type of object</typeparam>
    /// <param name="item">The calling item</param>
    /// <param name="range">An array or comma separated list of the items to check against the calling</param>
    /// <returns>True if item is found in list</returns>
    /// <remarks>Provides syntatic sugar by reordering the subject of the IEnumerable.Contains method</remarks>
    public static bool In<T>(this T item, params T[] range)
    {
        return range.Contains(item);
    }
}

Throw this inside any module in your assembly, preferably one named something like Utilities or ExtensionMethods. Now we can call like this:

personName.In("Sally","Jenny")

If you’re checking against a predefined list you can pass that in as a parameter and cast back into an array.

Personally, I take this utility method with me wherever I go. I find it incredibly helpful for checking if an item exists within a defined range. Once you start using it, you won’t stop, and I think that’s a good thing! For my money, it substantially improves readability, especially if you find yourself working on older code bases without collection initializers.

No comments:

Post a Comment