更新: 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 (first, middle, last) = LookupName(id1); // var outside
分解割り当てを使用して、既存の変数に分解することもできます。
(first, middle, last) = LookupName(id2); // deconstructing assignment
脱構築はタプルだけのものではありません。次の形式の(インスタンスまたは拡張)deconstructorメソッドがある限り、任意のタイプを分解できます。
public void Deconstruct(out T1 x1, ..., out Tn xn) { ... }
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];
これで、次のように記述できます(実際、これらのメソッドの1つをリファクタリングしました!):
points.Match((A, A2, B, C2, C) => {...});
私のソリューションはF#のパターンマッチングに似ており、この回答に触発されました:https ://stackoverflow.com/a/2321922/6659843