C#中的元组和解包赋值支持?

C#中的元组和解包赋值支持?,c#,tuples,iterable-unpacking,decomposition,C#,Tuples,Iterable Unpacking,Decomposition,我能用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 但在C#中,我发现自己在写作 int[] MyMethod() { // some work to find row and col return new int[] { r

我能用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
但在C#中,我发现自己在写作

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
蟒蛇的方式显然要干净得多。有没有办法在C#中做到这一点?

在.NET中有一组类:

Tuple<int, int> MyMethod()
{
    // some work to find row and col
    return Tuple.Create(row, col);
}
Tuple MyMethod()
{
//有些工作是为了找到行和列
返回元组。创建(行、列);
}
但是没有像Python那样的紧凑语法来解压它们:

Tuple<int, int> coords = MyMethod();
mylist[coords.Item1][coords.Item2] //do work on this element
Tuple-coords=MyMethod();
mylist[coords.Item1][coords.Item2]//处理此元素
C#是一种强类型语言,其类型系统强制执行一条规则,即函数可以没有(
void
)或有一个返回值。C#4.0引入了元组类:

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
Tuple MyMethod()
{
返回元组。创建(0,1);
}
//用法:
var myTuple=MyMethod();
var row=myTuple.Item1;//值为0
var col=myTuple.Item2;//值为1

扩展可能使它更接近Python元组解包,不是更高效,而是更可读(和Pythonic):

公共类扩展
{
公共静态void UnpackTo(这个元组t,out T1 v1,out T2 v2)
{
v1=t.1;
v2=t.2项;
}
}
元组方法()
{
//有些工作是为了找到行和列
返回元组。创建(行、列);
}
int row,col;
MyMethod().Unpacto(out row,out col);
mylist[行][col];//在这个元素上做一些工作

对于.NET 4.7及更高版本,您可以打包和解包
值组

(int, int) MyMethod()
{
    return (row, col);
}

(int row, int col) = MyMethod();
// mylist[row][col]
对于.NET 4.6.2及更早版本,您应该安装:


下面是一个带有值解包的zip示例。这里,zip返回元组上的迭代器

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);
}
输出:

1 -> one
2 -> two
3 -> three

我可能会为此使用out参数。@MikeChristensen:框架设计指南建议如果可以避免的话,就不要使用out参数。@MikeChristensen我考虑过out参数,但出于某些原因,它们让我感觉脏兮兮的,嗯,从未听过任何反对它们的争论
TryXXX()
方法似乎一直在使用它们。@MikeChristensen每次我使用时,我都想刺伤某人,因为他没有.NET中的Option/Maybe core的概念:-)因果读者注意:
Tuple
仅在.NET4+中是标准的。注意,对于其他读者来说,2元组可以在.NET<4(本质上)中创建通过使用KeyValuePair。强类型语言不限于返回单个值。方案就是一个例子。强打字!=静态分型;Python和Scheme是强类型但动态类型。确实如此,C#的类型系统可能会将函数的返回值限制为单个类型。此外,Go是强类型且静态类型,但支持多个返回值,您可以在此表达式中使用
var
。(不确定可以从哪个版本执行此操作)
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);
}
1 -> one
2 -> two
3 -> three