.Net 3.5 はタプルをサポートしていません。残念ですが、.net の将来のバージョンがタプルをサポートするかどうかはわかりませんか?
12 に答える
MSDN Magazine:BuildingTupleからこの記事を読みました。
抜粋は次のとおりです。
Microsoft .NET Frameworkの次の4.0リリースでは、System.Tupleと呼ばれる新しいタイプが導入されています。System.Tupleは、異種タイプのデータの固定サイズのコレクションです。
配列と同様に、タプルのサイズは固定されており、一度作成すると変更できません。配列とは異なり、タプルの各要素は異なるタイプである可能性があり、タプルは各要素の強い型付けを保証できます。
System.Collections.Generic名前空間のKeyValuePairには、Microsoft.NETFrameworkの周りに浮かんでいるタプルの例がすでに1つあります。KeyValuePairはTupleと同じように考えることができますが、どちらも2つのものを保持するタイプであるため、KeyValuePairは、格納する2つの値の間の関係を呼び起こすため、Tupleとは異なる感じがします(Dictionaryクラスをサポートしているため、正当な理由があります)。 )。
さらに、タプルは任意のサイズにすることができますが、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キーワードを使用すると、タプル変数の型アノテーションを削除できます。これにより、コードがいくらか読みやすくなります。
var t = new Tuple<string, int>("Hello", 4);
また、静的タプルクラスにいくつかのファクトリメソッドを追加しました。これにより、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...
}
Lokad共有ライブラリ(もちろんオープンソース)には、次の必要な機能を含む適切な(迅速ではない)C # Tuple実装があります。
- 2 ~ 5 個の不変タプルの実装
- 適切な DebuggerDisplayAttribute
- 適切なハッシュと等値チェック
- 提供されたパラメーター (ジェネリックはコンパイラーによって推測されます) からタプルを生成するためのヘルパーと、コレクションベースの操作のための拡張機能。
- 製造テスト済み。
Tuple クラスを実装するか、C# 内で F# クラスを再利用することは、話の半分にすぎません。これらにより、比較的簡単にタプルを作成できますが、実際には、F# のような言語で使用するのに便利な構文糖衣ではありません。
たとえば F# では、パターン マッチングを使用して、let ステートメント内のタプルの両方の部分を抽出できます。
let (a, b) = someTupleFunc
残念ながら、C# の F# クラスを使用して同じことを行うのは、あまりエレガントではありません。
Tuple<int,int> x = someTupleFunc();
int a = x.get_Item1();
int b = x.get_Item2();
タプルは、関数呼び出しから複数の値を返すための強力な方法であり、使い捨てのクラスでコードを散らかしたり、見苦しい ref や out パラメーターに頼ったりする必要はありません。ただし、私の意見では、それらの作成とアクセスをよりエレガントにするための構文糖衣がなければ、それらの用途は限られています。
私の意見では、匿名型の機能はタプルではなく、非常によく似た構造です。一部の LINQ クエリの出力は、タプルのように動作する匿名型のコレクションです。
以下は、型付きタプルをその場で作成するステートメントです:-):
var p1 = new {a = "A", b = 3};
C# は、ジェネリックを介して単純なタプルを非常に簡単にサポートし (以前の回答のように)、型推論を改善するための "マンブル タイピング" (多くの可能な C# 言語拡張機能の 1 つ) を使用すると、非常に強力になる可能性があります。
価値のあることとして、F# はタプルをネイティブにサポートしており、それを試してみると、(匿名の) タプルが多くを追加するかどうかはわかりません... 簡潔さで得られるものは、コードの明快さですぐに失われます。
単一のメソッド内のコードには、匿名型があります。メソッドの外に出るコードについては、単純な名前付き型に固執すると思います。もちろん、将来の C# でこれらを不変にするのが簡単になる場合 (操作は簡単ですが)、私は喜んでいます。
My open source .NET Sasa library has had tuples for years (along with plenty of other functionality, like full MIME parsing). I've been using it in production code for a good few years now.
これが私のタプルのセットです。それらは Python スクリプトによって自動生成されるため、おそらく少しやり過ぎました。
ユーザー名とパスワードが必要です。どちらもゲストです
これらは継承に基づいていますが、最初の 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<> が適切な代替手段です。同じことを行い、拡張可能な構造体またはクラスを作成することもできます。