I've clearly established how to make a generic Tuple as follows when the number of items is known in advance...
Type t = typeof(Tuple<,,>);
Type[] keys = new Type[] { typeof(string), typeof(string), typeof(int) };
Type specific = t.MakeGenericType(keys);
but what if the number of objects in the "keys" array is variable? How to you start the ball rolling with the initial assignment to "t"?
Cheers. Craig
Personally, I would have an array of the generic type definitions:
Type[] tupleTypes = {
typeof(Tuple<>),
typeof(Tuple<,>),
typeof(Tuple<,,>),
typeof(Tuple<,,,>),
typeof(Tuple<,,,,>),
typeof(Tuple<,,,,,>),
typeof(Tuple<,,,,,,>),
typeof(Tuple<,,,,,,,>),
};
You could do this in code, but it would be a bit of a pain... probably something like:
Type[] tupleTypes = Enumerable.Range(1, 8)
.Select(x => Type.GetType("System.Tuple`" + x)
.ToArray();
Or avoiding the array:
Type generic = Type.GetType("System.Tuple`" + keys.Length);
Type specific = generic.MakeGenericType(keys);
Yet another way of building tupleTypes
through Tuple.Create:
// once
Type[] tupleTypes = typeof(Tuple).GetMethods(BindingFlags.Public | BindingFlags.Static)
.Where(mi => mi.IsGenericMethod && mi.Name == "Create")
.Select(mi => mi.ReturnType.GetGenericTypeDefinition())
.Distinct() // make sure there is no duplicated return types
.OrderBy(t => t.GetGenericArguments().Length)
.ToArray(); // expect start from Tuple<>
// instant type creation
Type tupleType = tupleTypes[types.Length-1].MakeGenericType(types);
Of course that expects that class System.Tuple will contain static Create methods that only produces Tuple<...>.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With