Bringing the IN clause from SQL to C#

Since I have to work with T-SQL (MS SQL Server SQL dialect) a lot, I tend to miss the IN clause in C# sometimes. Checking if a value is equal to a list of possible values in SQL is quite elegant:

IF(1 IN(1,2,3))
	PRINT '1 is in the list'

That’s not the case in C#, where the above example would traditionally be reqritten like this:

if(1 == 1 || 1 == 2 || 1 == 3)
	Console.WriteLine("1 is in the list");


The alternatives
When the value list gets bigger and bigger, the above method gets not very readable and contains lots of duplication. It would be nicer to have something closer to the IN clause. Let’s see the alternatives.

The first thing we can do is put all the possible values into an array. Prior to LINQ, arrays did not have a public method to check if it contains some value, so we have to write some code for ourselves and it becomes even more messy:

int[] values = new int[] { 1, 2, 3 };
bool contains = false;

foreach(int value in values)
{
	if(value == 1)
	{
		contains = true;
		break;
	}
}

if(contains)
	Console.WriteLine("1 is in the list");

That’s not much better. Next, we can try to use a class with a Contains() method, like List, for example:

int[] values = new int[] { 1, 2, 3 };
List valueList = new List(values);

if(valueList.Contains(1))
	Console.WriteLine("1 is in the list");

That’s better, but it involves having the data twice, for the array and for the list, since the list copies values for it’s own use internally. To avoid that, we can take advantage of the fact, that Array already implements IList interface, thus simplifying our code to:

IList valueList = (IList)new [] { 1, 2, 3 };

if(valueList.Contains(1))
	Console.WriteLine("1 is in the list");

That’s even better. Of course, we could go on and inline the variable, which brings us this piece of code:

if(((IList)new [] { 1, 2, 3 }).Contains(1))
	Console.WriteLine("1 is in the list");

, but I don’t feel pleasure reading it. Using LINQ, we can make the code a little clearer and shorter:

if(new []{ 1, 2, 3 }.Contains(1))
	Console.WriteLine("1 is in the list");

Still not that readable as the IN clause.

So what can we do else to simplify it? I’d like it to look more like the IN syntax, so I came up with an extension method for the object class. Here it is, along with the above example rewritten:

public static class InClauseObjectExtensions
{
	public static bool In(this T @object, params T[] values)
	{
		// this is LINQ expression. If you don't want to use LINQ, you can use a simple foreach and return true if object is found in the array
		return values.Contains(@object);
	}

	public static bool In(this T @object, IEnumerable valueList valueList)
	{
		// this is LINQ expression. If you don't want to use LINQ, you can use a simple foreach and return true if object is found in the array
		return valueList.Contains(@object);
	}
}
...
if (1.In(1, 2, 3))
	Console.WriteLine("1 is in the list");

That looks almost like the IN clause! I’m using the params keyword, so all the arguments to the method would be put into an array that I can easily search my value in. The other overload, that takes an IEnumerable as argument is there in case you want to pass an array or some collection to the In() method. This comes handy when you already have an array, but still want to use the In() method instead of the LINQ Contains() extension method.

Too bad that extension methods are only supported from .NET 3.5, since we have many applications targeting .NET 2.0 😦

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s