List Tuple more than 8 items
Asked Answered
P

4

10

Can anyone help the following List Tuple more than 8 elements is not working:

List<Tuple<int, string, double, string, int, string, double, Tuple<int, string>>> tpl = new 
List<Tuple<int, string, double, string, int, string, double, Tuple<int, string>>>();
tpl.Add(Tuple.Create(1, "ABC", 100.123, "XYZ", 1, "ABC", 100.123, new Tuple<int, string>(100, "My Rest Item")));

foreach(var k in tpl)
        listBox1.Items.Add(k.Item1.ToString() + " ---> " + k.Item2.ToString() + " ---> " + k.Item3.ToString() + " ---> " +
        k.Item4.ToString() + " ---> " + k.Item5.ToString() + " ---> " + k.Item6.ToString() + " ---> " +
        k.Item7.ToString() + " ---> " + k.Rest.Item1.ToString());

It gives following error

Error 1 The best overloaded method match for 'System.Collections.Generic.List<System.Tuple<int,string,double,string,int,string,double,System.Tuple<int,string>>>.Add(System.Tuple<int,string,double,string,int,string,double,System.Tuple<int,string>>)' has some invalid arguments C:\Users\Hewlett Packard\AppData\Local\Temporary Projects\WindowsFormsApplication1\Form1.cs 68 17 WindowsFormsApplication1 and Error 2 Argument 1: cannot convert from 'System.Tuple<int,string,double,string,int,string,double,System.Tuple<System.Tuple<int,string>>>' to 'System.Tuple<int,string,double,string,int,string,double,System.Tuple<int,string>>' C:\Users\Hewlett Packard\AppData\Local\Temporary Projects\WindowsFormsApplication1\Form1.cs 68 25 WindowsFormsApplication1

Psychologism answered 17/6, 2014 at 12:17 Comment(1)
Aside from anything else - don't do this! Create your own named type with the relevant properties etc.Mong
M
22

The problem is with the last argument to Tuple.Create. Look carefully at how the argument return value is defined:

public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>>
    Create<T1, T2, T3, T4, T5, T6, T7, T8>(
    T1 item1,
    T2 item2,
    T3 item3,
    T4 item4,
    T5 item5,
    T6 item6,
    T7 item7,
    T8 item8
)

Basically, that wraps T8 in a Tuple<T8> automatically - and somewhat unhelpfully.

You can use new instead:

var value = new Tuple<<int, string, double, string, int, string, double,
                      Tuple<int, string>>
    (1, "ABC", 100.123, "XYZ", 1, "ABC", 100.123,
     new Tuple<int, string>(100, "My Rest Item"));

That's pretty ghastly though. It might be better to create some static methods yourself, e.g.

public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9>>
    Create(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9)
{
    return new Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9>>
        (t1, t2, t3, t4, t5, t6, t7, Tuple.Create(t8, t9)); 
}

(with as many overloads as you need)

or possibly an extension method on Tuple<T1 ... T7>:

public static Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>
    With(this Tuple<T1, T2, T3, T4, T5, T6, T7> tuple,
         TRest rest)
{
    return new Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>(
        tuple.Item1, 
        tuple.Item2, 
        tuple.Item3, 
        tuple.Item4, 
        tuple.Item5, 
        tuple.Item6, 
        tuple.Item7,
        rest);
}

Then you could use:

var value = Tuple.Create(1, "ABC", 100.123, "XYZ", 1, "ABC", 100.123)
                 .With(Tuple.Create(100, "My Rest Item"));

Personally I'd try to avoid having this size of tuple entirely though - create a named type with the appropriate properties, instead.

Mong answered 17/6, 2014 at 12:29 Comment(2)
So that would be a bug in the declaration of that factory method then? I can't really see a point of doing that.Architect
@LasseV.Karlsen: I suspect there's some reason for it, but it's not entirely clear what it is - it's certainly unhelpful in this use case.Mong
F
8

In C#7

var tup = (1, 2, 3, 4, 5, 6, 7, 8, "nine");
var one = tup.Item1;
var nine = tup.Item9;
Forest answered 9/11, 2017 at 23:38 Comment(2)
very relevant to mention itLashonlashond
Note that this creates a ValueTuple and not a Tuple.Menarche
S
3

I don't really understand why myself, but the code will work when you use new Tuple<> instead of Tuple.Create:

tpl.Add
( new Tuple<int, string, double, string, int, string, double, Tuple<int, string>>
  ( 1
  , "ABC"
  , 100.123
  , "XYZ"
  , 1
  , "ABC"
  , 100.123
  , Tuple.Create(100, "My Rest Item")
  )
);
Stereoscope answered 17/6, 2014 at 12:28 Comment(0)
W
0

I know this is old, but I struggled for many hours and I finally made it work with the approach below: method:

internal static Tuple<List<double>, List<string>, List<string>, List<string>, List<string>, List<int>, List<int>, Tuple<List<string>, List<int>>> YourMethodName(int something)

// do method work

return new Tuple<List<double>, List<string>, List<string>, List<string>, List<string>, List<int>, List<int>, Tuple<List<string>, List<int>>> (itme1, item2, item3, item4, item5, item6, item7, new Tuple<List<string>, List<int>>(item8, item9));

I was using return Tuple.Create(item1, item2 etc) and it was working until I tried to use item9 (it only can use 8 max, even if item 8 is a nested tuple, then after many hours of google and frustration I found this out.)

Wensleydale answered 15/12, 2021 at 11:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.