更新:在 C#7 中,您可以使用元组轻松地一次分配多个变量。为了将数组元素分配给变量,您需要编写适当的Deconstruct()
扩展方法:
使用元组的另一种方法是解构它们。解构声明是一种将元组(或其他值)拆分为其部分并将这些部分单独分配给新变量的语法:
(string first, string middle, string last) = LookupName(id1); // deconstructing declaration
WriteLine($"found {first} {last}.");
在解构声明中,您可以将 var 用于声明的各个变量:
(var first, var middle, var last) = LookupName(id1); // var inside
甚至在括号外放一个 var 作为缩写:
var (first, middle, last) = LookupName(id1); // var outside
您还可以使用解构赋值将现有变量解构:
(first, middle, last) = LookupName(id2); // deconstructing assignment
解构不仅仅适用于元组。任何类型都可以被解构,只要它具有以下形式的(实例或扩展)解构方法:
public void Deconstruct(out T1 x1, ..., out Tn xn) { ... }
out 参数构成解构产生的值。
(为什么它使用 out 参数而不是返回一个元组?这样你就可以对不同数量的值进行多个重载)。
class Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) { X = x; Y = y; }
public void Deconstruct(out int x, out int y) { x = X; y = Y; }
}
(var myX, var myY) = GetPoint(); // calls Deconstruct(out myX, out myY);
以这种方式让构造函数和解构函数“对称”将是一种常见的模式。
https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/
老答案:
事实上,您可以通过使用这样的扩展方法在 C# 中实现类似的功能(注意:我没有包括检查参数是否有效):
public static void Match<T>(this IList<T> collection, Action<T,T> block)
{
block(collection[0], collection[1]);
}
public static void Match<T>(this IList<T> collection, Action<T,T,T> block)
{
block(collection[0], collection[1], collection[2]);
}
//...
你可以像这样使用它们:
new[] { "hey", "now" }.Match((str1, str2) =>
{
Console.WriteLine(str1);
Console.WriteLine(str2);
});
如果需要函数的返回值,则可以使用以下重载:
public static R Match<T,R>(this IList<T> collection, Func<T, T, R> block)
{
return block(collection[0], collection[1]);
}
private string NewMethod1()
{
return new[] { "hey", "now" }.Match((str1, str2) =>
{
return str1 + str2;
});
}
这样:
缺点是你最终会得到额外的代码块,但我认为这是值得的。您可以使用代码片段以避免手动输入大括号等。
我知道这是一个 7 年前的问题,但不久前我需要这样一个解决方案 - 轻松为传递给方法的数组元素命名(不,使用类/结构而不是数组是不切实际的,因为对于相同的数组我可能在不同的方法中需要不同的元素名称),不幸的是我最终得到了这样的代码:
var A = points[0];
var A2 = points[1];
var B = points[2];
var C2 = points[3];
var C = points[4];
现在我可以写了(事实上,我现在已经重构了其中一种方法!):
points.Match((A, A2, B, C2, C) => {...});
我的解决方案类似于 F# 中的模式匹配,我受到这个答案的启发:https ://stackoverflow.com/a/2321922/6659843