System.Tupleクラスは、.NET 4.0から追加されたクラスです。
このクラスは「組」を表します。
よく日常会話でも言う
2つで一組とか3つで一組
の感じです。
Pythonやっている人にはおなじみですね。
.NETのタプルは、ジェネリック対応してますので型がきっちり決まります。
実際には、以下のように定義されています。
Tuple<T1> Tuple<T1, T2> Tuple<T1, T2, T3> Tuple<T1, T2, T3, T4> Tuple<T1, T2, T3, T4, T5> Tuple<T1, T2, T3, T4, T5, T6> Tuple<T1, T2, T3, T4, T5, T6, T7> Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>
みたまんまですが、8つ以上の組を作成する場合はTRestに含めます。
(8つ以上の組を作成する事があるのかどうかは別として)
で、オブジェクトを作成する場合は以下のようにCreate静的メソッドから作成します。
// int, intのタプル (Tuple<int, int>) var t1 = Tuple.Create(10, 20); // int, int, stringのタプル (Tuple<int, int, string>) var t2 = Tuple.Create(10, 20, "hoge");
各値は、それぞれItem1, Item2, Item3....のようにして取得します。
尚、上記のプロパティは読み取り専用(readonly)です。
あらかじめToStringメソッドがオーバーライドされていますので
そのままで、以下のような文字列表現が得られます。
Console.WriteLine(Tuple.Create(10, 20)); // (10, 20)
以下、サンプルです。
#region TupleSamples-01 public class TupleSamples01 : IExecutable { public void Execute() { // // Tupleクラスは、.NET 4.0から追加されたクラスである。 // 複数の値を一組のデータとして、保持することができる。 // // よく利用されるのは、戻り値にて複数の値を返す必要が有る場合などである。 // (objectの配列を返すという手もあるが、その場合Boxingが発生してしまうのでパフォーマンスが // 厳しく要求される場面では、利用しづらい。その点、Tupleはジェネリッククラスとなっているので // Boxingが発生する事がない。) // // Tupleクラスは、不可変のオブジェクトとなっている。つまり、コンストラクト時に値を設定した後は // その値を変更することが出来ない。(参照の先に存在しているメンバは変更可能。) // 各データは、「Item1」「Item2」・・・という形で取得していく。 // // 以下のようなクラス定義が行われており、データの数によってインスタンス化するものが変わる。 // Tuple<T1> // Tuple<T1, T2> // Tuple<T1, T2, T3> // Tuple<T1, T2, T3, T4> // Tuple<T1, T2, T3, T4, T5> // Tuple<T1, T2, T3, T4, T5, T6> // Tuple<T1, T2, T3, T4, T5, T6, T7> // Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> // // データ数が7つ以上の場合は、残りの部分をTRestとして設定する。 // // Tupleを作成する際は、Tuple.Createメソッドを利用してインスタンスを取得するのが楽である。 // また、その際は型推論を利用すると便利。 // // Tupleクラスでは、ToStringメソッドがオーバーライドされており、以下のように表示される。 // Tuple<int, int> ==> (xxx, yyy) // Tuple<int, string> t1 = Tuple.Create(100, "gsf_zero1"); var t2 = Tuple.Create(200, "gsf_zero2", 30); // Tuple<int, string, int>となる。 Console.WriteLine(t1.Item1); Console.WriteLine(t1.Item2); Console.WriteLine(t2.Item1); Console.WriteLine(t2.Item2); Console.WriteLine(t2.Item3); var t3 = TestMethod(10, 20); Console.WriteLine(t3); // (100, 400) // 以下はエラーとなる. // t3.Item1 = 1000; } private Tuple<int, int> TestMethod(int x, int y) { return Tuple.Create(x * x, y * y); } } #endregion
どのような場合に使うのか?ってなるのですが
これが私自身はっきりしてません。メソッドの戻り値として複数の値を返したい場合に便利とか
引数として利用するとか聞くのですが、私の場合は、それ用のクラスなり構造体を定義する事がほとんどなので
今のところ、サンプル以外で使ったことがありません。
パパッとコード書きたい時は便利です。
MSDNには以下のような利用法があると記述されています。
以下 http://msdn.microsoft.com/ja-jp/library/dd268536.aspxy より抜粋。
・1 つのデータセットを表現するため。たとえば、データベースのレコードを組で表現し、そのレコードの各フィールドを組の構成要素で表現できます。 ・データセットのアクセスと操作を容易にするため。 ・out パラメーター (C# の場合) または ByRef パラメーター (Visual Basic の場合) を使用せずに、メソッドから複数の値を返すため。 ・1 つのパラメーターを使用してメソッドに複数の値を渡すため。 たとえば、Thread.Start(Object) メソッドには、起動時にスレッドが実行するメソッドに 1 つの値を渡すために使用できる 1 つのパラメーターがあります。 このメソッドの引数として Tupleオブジェクトを指定すると、スレッドの起動ルーチンに 2 つのデータ項目を渡すことができます。
================================
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場