I have a List<object> and I want to convert it to Tuple<object, ..., object>. How can I do it for any Count of List (which is guaranteed to be short enough)?
1 Answer
Note, that unlike List<T>, tuple can have very limited numer of fields (7 + 1 in .Net 7)
https://learn.microsoft.com/en-us/dotnet/api/system.tuple-8?view=net-7.0
If the list is short enough, you can try to create tuple with a help of reflection (i.e. to call the required Tuple.Create method):
using System.Linq;
using System.Reflection;
...
// List<T>, not necessary List<Object>
List<int> data = new List<int>() { 4, 5, 7 };
...
var tuple = typeof(Tuple)
.GetMethods(BindingFlags.Static | BindingFlags.Public)
.First(method => method.Name == "Create" &&
method.GetParameters().Length == data.Count)
.MakeGenericMethod(Enumerable
.Repeat(data.GetType().GenericTypeArguments[0], data.Count)
.ToArray())
.Invoke(null, data.Select(item => (object) item).ToArray());
// Let's have a look:
Console.Write(tuple);
Output:
(4, 5, 7)
Note, that in such implementation, all fields of the tuple are of the same type (which is taken from list declaration). If you want to use actual item types change MakeGenericMethod call
...
.MakeGenericMethod(data.Select(item => item?.GetType() ?? typeof(object))
.ToArray())
...
6 Comments
BurnsBA
I was going to post the same answer but I realized -- how do you use this? If you make this a method, how do you communicate the return type in a useful manner?
Dmitrii Bychenko
@BurnsBA: I treat the question as an pure academic one: when given a list return a tuple (a pretty good exercise for reflection - static overload methods with differrent generic parameters). Since we can get any of
Tuple<T1>, Tuple<T1, T2>, ..., Tuple<T1, T2, ..., Tn> instances, hardly can we send these intances better than being cast to object...Mr.Price
Thank you! Could you please also tell me how can I create
TupleValue from Dictionary<srting, object> and preserve DataType? So I would like to convert new Dictionary<string, object>() { {"First": 1}, {"Second": "2"}} to (First: 1, Second: "2"). I guess that again Reflection must be used because I do not know the length of dictioanry in advance.Dmitrii Bychenko
@Mr.Price: You can create
ValueTuple with a help of reflection, but you can't specify fields' names: stackoverflow.com/questions/43565738/…Mr.Price
ohh :( Is there any other method to create
ValueTuple from Dictionary? Or in general, is it possible to write 8 functions (because we can have up to 8 values in ValueTuple) which enable me to pass my names of the values in ValueTuple? I mean a function public static GetValueTuple(string name1, ..., string name8, object value1, ..., object value8) which return ValueTuple with names name1,...,name8 and appropriate values? |
iforswitch-casestatements/expressions will enable you to do that...) It will not be the prettiest thing in the world, but it will do what you wish for (be always very, very cautious about what you wish for...).