I defined a tuples in a for loop like this (From Leetcode 1704)
for (var tuple = (i : 0, j : s.Length / 2); tuple.i < s.Length / 2 && tuple.j < s.Length; tuple.i , tuple.j ){...}
It worked properly.
Then I tried to explicitly define the variable type of the tuple.
This is the method I found on the Internet
for (Tuple<int, int> tuple = new Tuple<int, int>(i : 0, j : s.Length / 2); tuple.i < s.Length / 2 && tuple.j < s.Length; tuple.i , tuple.j )
And I got some errors
Line 7: Char 58: error CS1739: The best overload for 'Tuple' does not have a parameter named 'i' (in Solution.cs)
Line 7: Char 90: error CS1061: 'Tuple<int, int>' does not contain a definition for 'i' and no accessible extension method 'i' accepting a first argument of type 'Tuple<int, int>' could be found (are you missing a using directive or an assembly reference?) (in Solution.cs)
Line 7: Char 116: error CS1061: 'Tuple<int, int>' does not contain a definition for 'j' and no accessible extension method 'j' accepting a first argument of type 'Tuple<int, int>' could be found (are you missing a using directive or an assembly reference?) (in Solution.cs)
Line 7: Char 136: error CS1061: 'Tuple<int, int>' does not contain a definition for 'i' and no accessible extension method 'i' accepting a first argument of type 'Tuple<int, int>' could be found (are you missing a using directive or an assembly reference?) (in Solution.cs)
Line 7: Char 147: error CS1061: 'Tuple<int, int>' does not contain a definition for 'j' and no accessible extension method 'j' accepting a first argument of type 'Tuple<int, int>' could be found (are you missing a using directive or an assembly reference?) (in Solution.cs)
Line 9: Char 41: error CS1061: 'Tuple<int, int>' does not contain a definition for 'i' and no accessible extension method 'i' accepting a first argument of type 'Tuple<int, int>' could be found (are you missing a using directive or an assembly reference?) (in Solution.cs)
Line 10: Char 41: error CS1061: 'Tuple<int, int>' does not contain a definition for 'j' and no accessible extension method 'j' accepting a first argument of type 'Tuple<int, int>' could be found (are you missing a using directive or an assembly reference?) (in Solution.cs)
I want to know is it special to define a Tuple in a for loop? And how should I do it
(Of course it's clearer and easier to read with var... I just want to figure out how to do it without omitting.)
CodePudding user response:
A Tuple normally contains the properties Item1 and Item2. That's why you get the compilation errors in your 2nd example. It should look like this:
for (Tuple<int, int> tuple = new Tuple<int, int>(0, s.Length / 2);
tuple.Item1 < s.Length / 2 && tuple.Item2 < s.Length; tuple.Item1 , tuple.Item2 ) { }
But that doesn't work because Tuples are immutable and you cannot increment the items. Tuples in C# 6 are not strongly typed, that's why Microsoft introduced the ValueTuple in C# 7, which is a mutable struct. Like this it will work:
for (ValueTuple<int, int> tuple = new ValueTuple<int, int>(0, s.Length / 2);
tuple.Item1 < s.Length / 2 && tuple.Item2 < s.Length; tuple.Item1 , tuple.Item2 ) { }
If you just want to avoid the var keyword in your sample you could declare it like this:
for ((int i, int j) tuple = (i: 0, j: s.Length / 2);
tuple.i < s.Length / 2 && tuple.j < s.Length; tuple.i , tuple.j ) { }
CodePudding user response:
It doesn't matter where do you define the tuple. It matters how do you define it. Here is the correct definition (with items of type string
and int
):
Tuple<int, string> tuple = Tuple.Create<int, string>(0, "a string"); // Generic parameters are types of the elements
// Accessing the elements
int element1 = tuple.Item1;
A tuple can store up to 8 elements of different types.
CodePudding user response:
The "tuple" you defined in the loop isn't actually a System.Tuple<T1,T2>
, it's in fact something different called a ValueTuple
, check out this existing post for a good rundown of the differences:
What's the difference between System.ValueTuple and System.Tuple?