tabs ↹ over ␣ ␣ ␣ spaces

by Jiří {x2} Činčura

Checking whether the type is a tuple (ValueTuple)

27 Mar 2017 2 mins .NET, C#

Continuing with my tuples (ValueTuple<...> to be precise) exploration in C# I was in a need to check whether the type is a “tuple”. The (T, T, T, ...) in C#. You can create ValueTuple<...> yourself manually, but you can also create something that’s not a tuple – compiler wouldn’t do it that way.

For example ValueTuple<int, int, int, int, int, int, int, int> compiles fine, but the 8th element (TRest) should be another ValueTuple<int>. Similarly also plain int isn’t a tuple, obviously.

So I wrote a small helper for myself.

public static bool IsTuple(Type tuple)
{
	if (!tuple.IsGenericType)
		return false;
	var openType = tuple.GetGenericTypeDefinition();
	return openType == typeof(ValueTuple<>)
		|| openType == typeof(ValueTuple<,>)
		|| openType == typeof(ValueTuple<,,>)
		|| openType == typeof(ValueTuple<,,,>)
		|| openType == typeof(ValueTuple<,,,,>)
		|| openType == typeof(ValueTuple<,,,,,>)
		|| openType == typeof(ValueTuple<,,,,,,>)
		|| (openType == typeof(ValueTuple<,,,,,,,>) && IsTuple(tuple.GetGenericArguments()[7]));
}

To be touch bit sure it works as it should, here’s some tests (using NUnit).

[TestCase(typeof((int, int)), ExpectedResult = true)]
[TestCase(typeof((int, int, string, string, int, int, string, string, int, int)), ExpectedResult = true)]
[TestCase(typeof(int), ExpectedResult = false)]
[TestCase(typeof(ValueTuple<int, int, int, int, int, int, int, int>), ExpectedResult = false)]
[TestCase(typeof(ValueTuple<int, int, int, int, int, int, int, ValueTuple<string, string>>), ExpectedResult = true)]
public bool IsTupleTest(Type tuple)
{
	return TupleHelper.IsTuple(tuple);
}

There’s one small catch, though. You can’t really create a ValueTuple<T> (on a top level) using C# (T) syntax, because for the compiler the ( and ) are just plain parentheses, but I consider that for me as a valid tuple anyway.

Profile Picture Jiří Činčura is an independent developer, .NET, C# and Firebird expert, focusing on data and business layers, language constructs, parallelism, databases and performance. He's Microsoft Most Valuable Professional and frequent speaker. You can read his articles, guides and tips and tricks at www.tabsoverspaces.com.