2010-11-24 4 views
10

複数の値を送信することはよくありますが、使用頻度が低い(1か所または2か所でのみ使用される)ため、新しいタイプの作成を正当化することは困難です。タプルをC#で扱いやすくするヒントはありますか?

Tuple<...>およびKeyValuePair<,>タイプは非常に便利ですが、実際の言語サポートはありません。

タプルのリストに使用するうまい方法は、リストを拡張し、カスタムの追加メソッドを追加するタイプを作成することです。

public class TupleList<T1,T2> : List<Tuple<T1,T2>>{ 
    public void Add(T1 key, T2 value){ 
     base.Add(Tuple.Create(key, value)); 
    } 
} 

これは私がIEnumerable<Tuple<int,string>>を取る方法を持っている場合、私はすぐにそうのようなリストを構築するために、次のコードを使用することができることを意味::

Foo(new TupleList<int,string>{{1,"one"},{2,"two"},{3,"three"}}); 

これはタプルに値を巻きます我々は常にTuple.Createと言っておく必要はないので、リストが簡単になり、機能的な言語の構文に似ています。

タプルで作業する場合、さまざまなコンポーネントに巻き戻すと便利です。この拡張メソッドは、この点では役に立ちます。

public static void Unwind<T1,T2>(this Tuple<T1,T2> tuple,out T1 var1,out T2 var2) 
    { 
     var1 = tuple.Item1; 
     var2 = tuple.Item2; 
    } 

でも、outパラメータが変わっても、それはまったく変わっていません。つまり、T1が文字列の場合、割り当て可能であってもオブジェクト変数を送信することはできません。そうでなければ手で巻き戻すことができます。私はあなたがこの分散を望む理由を本当に示唆することはできませんが、もしそれがあれば、あなたがそれを失いたい理由がわかりません。

誰もがC#で作業タプルやタプルなどのオブジェクトを作成するのに役立つヒントを持っていますか?

タプルの重要な潜在的な用途は、一般的なメモです。 F#のような言語では非常に簡単ですが、C#では難しいです。

私は現在、特定のメンバフィールドを構築するために動的に構築されたオブジェクトに提供されるMethodBaseとトークンの配列(定数、オブジェクト、または引数トークン)を供給するためにTuplesを使用しています。

APIコンシューマで構文を簡単にしたいので、ConstructorInfoまたはMethodInfoとオブジェクトのparams配列をとることができるAddメソッドを作成しました。

編集:いつものように エリックリペットはここにタプルを使用するための優れた動機を持っているし、彼も私が実際にはサポートされていませんが疑わ何と言う: What requirement was the tuple designed to solve?

+0

実際に何を入力するのではなく、オブジェクト型のパラメータを渡す方が望ましい場合を教えてください。つまり、コンテキストの少しだけ「アンワインド」を呼び出す方法を教えてください。 –

+1

の出力パラメータは厳密なものなので、選択肢として推奨されていません。私はF#のようなAPIのサポートを殺すだろうが、これはパラメータをタプルに変換する。 –

+0

継承を超える構成! – Eric

答えて

4

使用モノが!彼らはbinding variables to tuple membersのための実験的なサポートを持っているので、あなたは、これはあなたには、いくつかのより良いを提供することを可能にする、タプルがある、ジェネリック型を別名閉じすることができますC#では

(user, password, host, port, path) = ParseUri (url); 
+13

それはかなり悪いアドバイスです。確かに、この機能はきちんとしていますが、「モノを使う」は多くの人ができる決定ではありません。 –

+6

残念ながら、私はコンパイルするランタイムを変更することはできません。 –

+0

+実験的サポート – Eric

5

のようなコードを使用して

Tuple<string, string, string, int, string> ParseUri (string url); 

のようなメソッドを呼び出すことができます何が意図されているかについての洞察コードを大きく変更することはありませんが、以下の例を見ると、GetTempが返すものの意図がより良くなります。エイリアスなし

:別名で

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var result = GetTemp(10, 10); 
      Console.WriteLine("Temp for {0} is {1}", result.Item2, result.Item1); 
     } 

     // You give a lat & a long and you get the closest city & temp for it 
     static Tuple<double, string> GetTemp(double lat, double @long) 
     { 
      // just for example 
      return Tuple.Create(10d, "Mordor"); 
     }   
    } 
} 

namespace ConsoleApplication1 
{ 
    using CityTemp = Tuple<double, string>; 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var result = GetTemp(10, 10); 
      Console.WriteLine("Temp for {0} is {1}", result.Item2, result.Item1); 
     } 

     // You give a lat & a long and you get the closest city & temp for it 
     static CityTemp GetTemp(double lat, double @long) 
     { 
      // just for example    
      return new CityTemp(10, "Mordor"); 
     } 
    } 
} 
2

基本的にあなたがsoethingを行うことができますC#7/Visual Studioに15

来る素晴らしいタプル機能がありますそのように

static (int x, int y) DoSomething() 
{ 
    return (1, 2); 
} 

static void Test() 
{ 
    var cool = DoSomething(); 
    var value = cool.x; 
} 

以下を参照してくださいpost

関連する問題