.Net 3.5はタプルをサポートしていません。残念ですが、.netの将来のバージョンがタプルをサポートするかどうかはわかりませんか?
MSDN Magazineからこの記事を読んだばかりです。 Building Tuple
抜粋は次のとおりです。
Microsoft .NET Frameworkの今後の4.0リリースでは、System.Tupleと呼ばれる新しいタイプが導入されます。 System.Tupleは、不均一に型指定されたデータの固定サイズのコレクションです。
配列と同様に、タプルのサイズは固定されており、作成後は変更できません。配列とは異なり、Tupleの各要素は異なる型である場合があり、Tupleは各要素の厳密な型指定を保証できます。
System.Collections.Generic名前空間には、Microsoft .NET Frameworkの周りに浮かぶTupleの例が1つあります:KeyValuePair。 KeyValuePairはTupleと同じと考えることができますが、どちらも2つのことを保持するタイプであるため、KeyValuePairは、格納する2つの値間の関係を誘発するため、Tupleとは異なる感じがします)。
さらに、タプルのサイズは任意に設定できますが、KeyValuePairにはキーと値の2つのものしかありません。
F#のような一部の言語にはタプル用の特別な構文がありますが、任意の言語から新しい共通のタプル型を使用できます。最初の例を再検討すると、タプルの構文がない言語では、有用ではあるがタプルが非常に冗長になることがわかります。
class Program {
static void Main(string[] args) {
Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
PrintStringAndInt(t.Item1, t.Item2);
}
static void PrintStringAndInt(string s, int i) {
Console.WriteLine("{0} {1}", s, i);
}
}
C#3.0のvarキーワードを使用して、Tuple変数の型シグネチャを削除できます。これにより、コードが多少読みやすくなります。
var t = new Tuple<string, int>("Hello", 4);
また、静的なTupleクラスにいくつかのファクトリメソッドを追加しました。これにより、C#などの型推論をサポートする言語でタプルを簡単に構築できます。
var t = Tuple.Create("Hello", 4);
#region tuples
public class Tuple<T>
{
public Tuple(T first)
{
First = first;
}
public T First { get; set; }
}
public class Tuple<T, T2> : Tuple<T>
{
public Tuple(T first, T2 second)
: base(first)
{
Second = second;
}
public T2 Second { get; set; }
}
public class Tuple<T, T2, T3> : Tuple<T, T2>
{
public Tuple(T first, T2 second, T3 third)
: base(first, second)
{
Third = third;
}
public T3 Third { get; set; }
}
public class Tuple<T, T2, T3, T4> : Tuple<T, T2, T3>
{
public Tuple(T first, T2 second, T3 third, T4 fourth)
: base(first, second, third)
{
Fourth = fourth;
}
public T4 Fourth { get; set; }
}
#endregion
そして、宣言をきれいにするには:
public static class Tuple
{
//Allows Tuple.New(1, "2") instead of new Tuple<int, string>(1, "2")
public static Tuple<T1, T2> New<T1, T2>(T1 t1, T2 t2)
{
return new Tuple<T1, T2>(t1, t2);
}
//etc...
}
proper(高速ではありません)C#Tupleの実装があります- Lokad Shared Libraries (もちろん、オープンソース)これには、次の必須機能が含まれます。
タプルクラスの実装またはC#内でのF#クラスの再利用は、話の半分に過ぎません。これらは、タプルを比較的簡単に作成する機能を提供しますが、実際にはF#などの言語で使用するのに最適な構文シュガーではありません。
たとえば、F#では、パターン一致を使用して、letステートメント内のTupleの両方の部分を抽出できます。たとえば、
let (a, b) = someTupleFunc
残念ながら、C#のF#クラスを使用して同じことを行うのは、それほどエレガントではありません。
Tuple<int,int> x = someTupleFunc();
int a = x.get_Item1();
int b = x.get_Item2();
タプルは、使い捨てのクラスでコードを散らしたり、ugいrefまたはoutパラメーターに頼ったりすることなく、関数呼び出しから複数の値を返すための強力なメソッドを表します。しかし、私の意見では、作成とアクセスをよりエレガントにするための構文上の砂糖がなければ、それらの使用は限られています。
私の意見では、匿名型機能はタプルではなく、非常によく似た構造です。一部のLINQクエリの出力は、タプルのように動作する匿名型のコレクションです。
ここに、型付きタプルを作成するステートメントがあります:-)その場で:
var p1 = new {a = "A", b = 3};
C#7は、タプルをネイティブでサポートします。
var unnamedTuple = ("Peter", 29);
var namedTuple = (Name: "Peter", Age: 29);
(string Name, double Age) typedTuple = ("Peter", 29);
私のオープンソース.NET Sasaライブラリ には、長年にわたってタプルがありました(完全なMIME解析など、他の多くの機能とともに)。数年前から本番コードで使用しています。
C#は、ジェネリックを介して簡単なタプルをサポートします(以前の回答による)。また、型推論を改善するための「mumbletyping」(多くのC#言語拡張機能の1つ)により、非常に強力になります。
それが価値があることについて、F#はタプルをネイティブにサポートし、それで遊んだので、(匿名の)タプルが多くを追加するかどうかわかりません...あなたが簡潔に失うものを失うveryコードですぐに明快さ。
単一のメソッド内のコードには、匿名型があります。メソッドの外に出るコードについては、単純な名前付き型に固執すると思います。もちろん、将来のC#でこれらを不変にすることが容易になったら(それでも作業が簡単になります)、私は満足します。
タプルのセットは次のとおりです。これらはPythonスクリプトによって自動生成されます。
ユーザー名/パスワードが必要です。両方ともguest
これらは継承に基づいていますが、最初の2つのメンバーの値が同じであっても、Tuple<Int32,String>
はTuple<Int32,String,Boolean>
と比較されません。
また、GetHashCodeやToStringなど、および多数の小さなヘルパーメソッドも実装します。
使用例:
Tuple<Int32, String> t1 = new Tuple<Int32, String>(10, "a");
Tuple<Int32, String, Boolean> t2 = new Tuple<Int32, String, Boolean>(10, "a", true);
if (t1.Equals(t2))
Console.Out.WriteLine(t1 + " == " + t2);
else
Console.Out.WriteLine(t1 + " != " + t2);
出力されます:
10, a != 10, a, True
コンピューターサイエンスクラスを正しく覚えていれば、タプルは単なるデータです。
グループ化されたデータが必要な場合-プロパティを含むクラスを作成します。 KeyValuePair のようなものが必要な場合は、そこにあります。
これらをハッシュテーブルまたは辞書で使用するには、GetHashCodeおよびEqualsのオーバーロードを提供する必要があります。
驚くでしょう-C#は強く型付けされた言語ですが、タプルはより動的に型付けされた言語に適しています。 C#は時間が経つにつれてよりダイナミックに変化してきましたが、それは構文上のシュガーであり、基礎となるデータ型の本当の変化ではありません。
1つのインスタンスに2つの値が必要な場合、KeyValuePair <>は、不器用ではありますが、適切な代替です。また、同じことを行い、拡張可能な構造体またはクラスを作成することもできます。