Tuples and unpacking assignment support in C#?
Solution 1
There's a set of Tuple classes in .NET:
Tuple<int, int> MyMethod()
{
// some work to find row and col
return Tuple.Create(row, col);
}
But there's no compact syntax for unpacking them like in Python:
Tuple<int, int> coords = MyMethod();
mylist[coords.Item1][coords.Item2] //do work on this element
Solution 2
For .NET 4.7 and later, you can pack and unpack a ValueTuple
:
(int, int) MyMethod()
{
return (row, col);
}
(int row, int col) = MyMethod();
// mylist[row][col]
For .NET 4.6.2 and earlier, you should install System.ValueTuple:
PM> Install-Package System.ValueTuple
Solution 3
An extension might get it closer to Python tuple unpacking, not more efficient but more readable (and Pythonic):
public class Extensions
{
public static void UnpackTo<T1, T2>(this Tuple<T1, T2> t, out T1 v1, out T2 v2)
{
v1 = t.Item1;
v2 = t.Item2;
}
}
Tuple<int, int> MyMethod()
{
// some work to find row and col
return Tuple.Create(row, col);
}
int row, col;
MyMethod().UnpackTo(out row, out col);
mylist[row][col]; // do work on this element
Solution 4
Here is a zip example with value unpacking. Here zip returns an iterator over tuples.
int[] numbers = {1, 2, 3, 4};
string[] words = {"one", "two", "three"};
foreach ((var n, var w) in numbers.Zip(words, Tuple.Create))
{
Console.WriteLine("{0} -> {1}", n, w);
}
Output:
1 -> one
2 -> two
3 -> three
Solution 5
C# is a strongly-typed language with a type system that enforces a rule that functions can have either none (void
) or 1 return value. C# 4.0 introduces the Tuple class:
Tuple<int, int> MyMethod()
{
return Tuple.Create(0, 1);
}
// Usage:
var myTuple = MyMethod();
var row = myTuple.Item1; // value of 0
var col = myTuple.Item2; // value of 1
Related videos on Youtube
maria nabil
Likes: [java, python, bounded lists] Dislikes: cucumbers, dangling commas, Feel free to look me up on the linked in machine https://www.linkedin.com/in/john-borries-87256165/
Updated on June 04, 2022Comments
-
maria nabil almost 2 years
In Python I can write
def myMethod(): #some work to find the row and col return (row, col) row, col = myMethod() mylist[row][col] # do work on this element
But in C# I find myself writing out
int[] MyMethod() { // some work to find row and col return new int[] { row, col } } int[] coords = MyMethod(); mylist[coords[0]][coords[1]] //do work on this element
The Pythonic way is obivously much cleaner. Is there a way to do this in C#?
-
Mike Christensen over 12 yearsI'd probably use out parameters for that..
-
Feidex over 12 years@MikeChristensen: The Framework Design Guidelines recommend against out parameters if they can be avoided.
-
maria nabil over 12 years@MikeChristensen I thought about out parameters, but they make me feel dirty for some reason
-
Admin over 12 years@MikeChristensen And every-time I use then I want to stab someone [with a rubber knife] for not having the concept of Option/Maybe core in .NET :-)
-
-
Admin over 12 yearsNote for causal reader:
Tuple<...>
is standard in .NET4+ only. -
fabspro about 10 yearsNote for other readers, a 2-tuple can be created in .NET < 4 (in essence) by using a KeyValuePair instead.
-
0dminnimda over 3 yearsnote that you can use
var
in this expression. (not sure which version this is possible from)