タプルの新しいC#機能を探しています。タプルはどのような問題を解決するように設計されていましたか?
アプリでタプルを何に使用しましたか?
更新
これまでの回答に感謝します。私の心に物事がまっすぐにあるかどうかを見てみましょう。タプルの良い例が座標として指摘されています。これは正しく見えますか?
var coords = Tuple.Create(geoLat,geoLong);
次に、タプルを次のように使用します。
var myLatlng = new google.maps.LatLng("+ coords.Item1 + ", "+ coords.Item2 + ");
あれは正しいですか?
プログラムを作成するとき、クラスを作成することを正当化するのに十分な共通性を持たない値のセットを論理的にグループ化することが非常に一般的です。
多くのプログラミング言語では、1つの方法で型を作成することなく、他の方法では無関係な値のセットを論理的にグループ化できます。
void M(int foo, string bar, double blah)
論理的には、これはint、string、doubleの3タプルである1つの引数を取るメソッドMとまったく同じです。しかし、私はあなたが実際に作らないことを願っています:
class MArguments
{
public int Foo { get; private set; }
... etc
mArgumentsがビジネスロジックで他の意味を持たない限り。
「クラスよりも軽量な構造で他の関係のないデータの集まりをグループ化する」という概念は、メソッドの正式なパラメータリストだけでなく、多くの場所で役立ちます。メソッドに返すものが2つある場合や、1つではなく2つのデータからディクショナリをキー設定する場合などに便利です。
Tuple型をネイティブにサポートするF#などの言語は、ユーザーに大きな柔軟性を提供します。これらは非常に便利なデータ型のセットです。 BCLチームは、F#チームと協力して、フレームワークの1つのTupleタイプを標準化して、すべての言語がそれらから利益を得られるようにすることを決定しました。
ただし、この時点では、C#でのタプルのlanguageサポートはありません。タプルは、他のフレームワーククラスのような別のデータ型です。それらについて特別なことは何もありません。 C#の仮想の将来のバージョンで、タプルのより良いサポートを追加することを検討しています。タプルを含むどのような機能が見たいかについて誰かが考えているなら、私はそれらを設計チームに伝えたいです。現実的なシナリオは、理論的な黙想よりも説得力があります。
タプルはコレクションの不変の実装を提供します
タプルの一般的な使用は別として:
不変オブジェクトは本質的にスレッドセーフです:
不変オブジェクトは、マルチスレッドアプリケーションで役立ちます。複数のスレッドは、他のスレッドによって変更されるデータを気にすることなく、不変オブジェクトによって表されるデータに作用できます。したがって、不変オブジェクトは、可変オブジェクトよりもスレッドセーフであると見なされます。
"Immutable Object" ウィキペディアから
応答の一部として複数の新しいオブジェクトを返す必要があるメソッドがある場合、ref
またはout
の代替手段を提供します。
また、2つまたは3つの既存の型をマッシュアップするだけで、この組み合わせだけにクラス/構造を追加する必要がない場合は、組み込み型を戻り値型として使用できます。 (関数が匿名型を返すことを望みますか?これは、その状況に対する部分的な答えです。)
多くの場合、「ペア」タイプを使用すると便利です。これは、迅速な状況(メソッドから2つの値を返すなど)でのみ使用されます。タプルはF#のような関数型言語の中心的な部分であり、C#は途中でそれらを選択しました。
関数から2つの値を返すのに非常に便利です
個人的には、調査サイクル、または単に「プレイ」しているとき、タプルは開発の反復的な部分であることがわかります。 Tupleはジェネリックなので、ジェネリックパラメーターを操作するとき、特にジェネリックコードを開発したいとき、そして「この呼び出しをどのようにしたいのか」と自問するのではなく、コードの最後から始めます。見に?」。
Tupleが形成するコレクションがリストの一部になり、List>を見つめることは、リストの意図や動作を実際に表していないことをよく理解します。私はしばしば「生きて」いますが、リストを操作し、値を変更したいことに気づきました-その時点で、必ずしもそのための新しいタプルを作成したくないので、独自のクラスまたは構造体を作成する必要があります保持するため、操作コードを追加できます。
もちろん、拡張メソッドは常に存在しますが、多くの場合、追加コードを一般的な実装に拡張したくない場合があります。
データをタプルとして表現したいが、タプルが利用できない場合がありました。 (VS2008)この場合、独自のTupleクラスを作成したばかりで、スレッドセーフ(不変)にしません。
だから私は、タプルはその目的を説明する型名を失うことを犠牲にして怠programmingなプログラミングであるという意見だと思います。他の費用は、パラメーターとして使用される場合はどこでも、タプルの署名を宣言する必要があることです。肥大化したように見えるいくつかのメソッドの後、メソッドシグネチャをクリーンアップするため、クラスを作成する価値があると感じるかもしれません。
私は、クラスを既に作業しているクラスのパブリックメンバーとして開始する傾向があります。しかし、値の単なるコレクションを超えた瞬間に、それは独自のファイルになり、それを含むクラスから移動します。
ですから、振り返ってみると、クラスを辞めたくないときにタプルを使い、今書いていることについて考えたいだけです。つまり、このメソッドに必要なデータと、返される値がどのように返されるのかを把握しながら、テキストの30分でTupleの署名が大幅に変更される可能性があります。
コードをリファクタリングする機会があれば、その中のタプルの場所に疑問を投げかけることがよくあります。
2010年以来の古い質問、そして2017年にはDotnetが変更され、よりスマートになりました。
C#7では、タプルの言語サポートが導入されています。これにより、より効率的な新しいタプル型を使用して、タプルのフィールドのセマンティック名が有効になります。
Vs 2017および.Net 4.7(またはnugetパッケージSystem.ValueTupleのインストール)では、非常に効率的で簡単な方法でタプルを作成/使用できます。
var person = (Id:"123", Name:"john"); //create tuble with two items
Console.WriteLine($"{person.Id} name:{person.Name}") //access its fields
メソッドから複数の値を返す:
public (double sum, double average) ComputeSumAndAverage(List<double> list)
{
var sum= list.Sum();
var average = sum/list.Count;
return (sum, average);
}
How to use:
var list=new List<double>{1,2,3};
var result = ComputeSumAndAverage(list);
Console.WriteLine($"Sum={result.sum} Average={result.average}");
詳細については、以下を参照してください。 https://docs.Microsoft.com/en-us/dotnet/csharp/tuples
Tupleは、特定のタイプを作成したくない場合に、関数から複数の値を返すためによく使用されます。 Pythonに精通している場合、Pythonはこれを長い間持っていました。
一般的な用途は、2つのフィールドのみを含むクラス/構造の作成を回避することであり、代わりにTuple(または、現時点ではKeyValuePair)を作成します。戻り値として便利です。Nout paramsを渡さないでください...
関数から複数の値を返します。 getCoordinates()は、xまたはyまたはzを返すだけの場合はあまり役に立ちませんが、3つのintを保持するための完全なクラスとオブジェクトの作成もかなり重いようです。
ディクショナリのキーと値のペアを反復処理するために、C#でKeyValuePairが更新されているのがわかります。
関数から値を返すときに非常に役立ちます。複数の値を戻すことができますが、これはいくつかのシナリオではかなり節約できます。
TuplesとKey-Valueのペアの間でこのパフォーマンスベンチマークを見つけたので、おそらくおもしろいでしょう。要約すると、Tupleはクラスであるため有利であり、したがってスタックではなくヒープに格納され、引数として渡されるとポインタが唯一のものになると言われています。ただし、KeyValuePairは構造体なので、割り当てるのは高速ですが、使用する場合は遅くなります。