Поддержка кортежей и распаковки в С#?
В Python я могу написать
def myMethod():
#some work to find the row and col
return (row, col)
row, col = myMethod()
mylist[row][col] # do work on this element
Но в С# я нахожу, что пишу
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
Питонический путь намного более чист. Есть ли способ сделать это в С#?
Ответы
Ответ 1
В .NET есть набор классов Tuple:
Tuple<int, int> MyMethod()
{
// some work to find row and col
return Tuple.Create(row, col);
}
Но нет компактного синтаксиса для их распаковки, как в Python:
Tuple<int, int> coords = MyMethod();
mylist[coords.Item1][coords.Item2] //do work on this element
Ответ 2
С С# 7 вы можете использовать ValueTuple:
Install-Package System.ValueTuple
Затем вы можете упаковать и распаковать ValueTuples
:
(int, int) MyMethod()
{
return (row, col);
}
(int row, int col) = MyMethod();
// mylist[row][col]
Ответ 3
Расширение может приблизить его к распаковке кортежей Python, не более эффективному, но более читаемому (и 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
Ответ 4
С# - строго типизированный язык с системой типов, которая обеспечивает правило, что функции могут иметь либо none (void
), либо 1 возвращаемое значение. С# 4.0 представляет класс Tuple:
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