Creating an '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 syntactic 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 syntactic 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.