7

私は時々C#3.0で、タプルの概念をシミュレートする方法を探しています。時が経つにつれて、私はさまざまな「貧乏人」の実装を行ってきました。それらのいくつかを次に示します。

基本オブジェクト配列

object[] poorTuple = new object[]{foo,bar,baz}; // basic object array

もっと強くタイプされた、HoHoHo .. ..

KeyValuePair<TypeA, KeyValuePair<TypeB, TypeC>> poorTuple;

型推論を使用できるクラスの実装(実世界の関数型プログラミングから引き上げられました)

public static class Tuple{
  public static Tuple<T1, T2> Create<T1 foo, T2 bar>{
    return new Tuple<T1, T2>(foo, bar);
  }
}
// later: 
var data = Tuple.Create("foo", 42);

質問:

  1. C#3.0(またはデータ構造が不足している言語を選択)で貧乏人のタプルを作成するその他の方法。

  2. C#3.0でタプルを取得するための最良の方法は何ですか?誰かがライブラリの推奨事項を持っている場合は、それを歓迎します。

  3. リストやタプルのようなものではなく、特定のタイプを作成することは、どの時点で(はい、私にとって一般化して)意味がありますか?(経験則を探しています)

4

7 に答える 7

8

有用な名前を除いて、タプルと同様に機能する匿名型を作成できます。

var itemsWithChildCounts 
    = myObjects.Select(x => new { Name = x.Name, Count = x.Children.Count() });
于 2009-11-30T22:06:58.313 に答える
5

これは、VisualStudioMagazineの2007年4月版のBillWagnerの記事から抜粋したジェネリックタプルのコードです。

public struct Tuple<T1, T2> : IEquatable<Tuple<T1, T2>>
{
    private readonly T1 first;
    public T1 First
    {
        get { return first; }
    }

    private readonly T2 second;
    public T2 Second
    {
        get { return second; }
    } 

    public Tuple(T1 f, T2 s)
    {
        first = f;
        second = s;
    }

    #region IEquatable<Tuple<T1,T2>> Members
    public bool Equals(Tuple<T1, T2> other)
    {
        return first.Equals(other.first) && 
            second.Equals(other.second);
    }

    public override bool Equals(object obj)
    {
        if (obj is Tuple<T1, T2>)
            return this.Equals((Tuple<T1, T2>)obj);
        else
            return false;
    }

    public override int GetHashCode()
    {
        return first.GetHashCode() ˆ second.GetHashCode();
    }
    #endregion
}
于 2009-12-01T15:12:04.130 に答える
1

1〜2の場合:独自のタプルクラスを実装することをお勧めします。あなたが盗んだ実装はまともなものです。それはうまくいくはずです。

3の場合:これが私の親指のルールです-この機能を複数のメソッド(同じタイプが同じ意味を持つ)で再利用する場合、またはパブリックAPIで使用する場合は、実装するときが来たと思います特定のタイプの「実際の」クラス。

于 2009-11-30T22:11:20.163 に答える
0
  1. 「クラスの実装」メソッドは、取得するのと同じくらい優れています(とにかく、次のバージョンの.NETに含まれているはずです)。
  2. 今のところ、私はそれらを自分のクラスの個人ライブラリに保管しています。
  3. 彼らが一般に公開されたらすぐに(つまり、クラスの関連する値を内部に格納するためだけに使用されなくなったとき)、適切なクラスを作成することを検討します。
于 2009-11-30T22:12:15.887 に答える
0

あなたが意見を求めたので、私は常にタイプを作成することになるでしょう-私はそうしない理由を理解することはできません。

多くの場合、実際にタイプが必要であることがわかります(主な用途は、コレクションに2つのアイテムを格納するか、メソッド呼び出しから2つのアイテムを返すことです。どちらの場合も、アイテムが密接に関連していない場合は、おそらく何か間違ったことをしている)。

于 2009-11-30T22:15:25.990 に答える
0

プログラムに新しい値セットを導入することが理にかなっている場合は、新しいタイプを作成するのが良いと思います。たとえば、複雑な電卓を作成している場合は、複素数型を作成します。いくつかの変数を少しの間「接着」したいだけの場合は、タプルの方がおそらく良い選択です。コンソールから2つの数値を収集する単純な関数があるとしましょう...次のようなことを行うことができます。

static void GetNumbers(out int x, out int y) { ... }
...
int x, y;
GetNumbers(out x, out y);

通常、「getter」関数に戻り値がある場合は理にかなっていると思いますが、この場合は、実際には2つの戻り値を持つことができないため、意味がありません。TwoNumbersという新しいタイプを作成して使用することもできますが、これは解決策というよりもすぐに問題になると思います。C#にタプルがある場合、次のようなことができる可能性があります。

static (int, int) GetNumbers() { ... }
...
int x, y;
(x, y) = GetNumbers();

ここで本当に興味深い質問は、C#にはこの機能がありませんが、ライブラリを使用して自分で実装できるかどうかです。あなたが提案するコードは始まりですが、2番目の例で行ったように割り当てることはできません。C#についてはよくわかりませんが、C ++では、戻り値が参照型の場合に関数呼び出しを代入演算子の左オペランドにすることができるという事実を利用することで、これに非常に近づけることができます。次のことを考慮してください。

// this class is implemented much like yours only with C++
template<typename T1, typename T2> class tuple { ... }
...
template<typename T1, typename T2> tuple<T1, T2>& tie(T1 a, T2 b) { ... }
...
template<typename T1, typename T2> tuple<T1, T2> get_numbers() { ... }
...
int x, y;
tie(x, y) = get_numbers();

私はそれがかなり近いと思います...(x, y) =私たちが持っている代わりにtie(x, y) =。実装の詳細に興味がある場合は、私が最初にこれについて学んだTR1ライブラリを参照してください。

http://www.boost.org/doc/libs/1_41_0/libs/tuple/doc/tuple_users_guide.html#tiers

したがって、これらすべてをC#3.0に戻すために...あなたが示したように、確かにジェネリックタプルクラスを作成できますが、C#でタプルを「解凍」するためのtieのような関数を作成できますか?私はそれを試していません、楽しそうですね。そのようなものがなければ、C#タプルライブラリをコード全体で増殖させるのは気が進まないでしょう。

于 2009-12-16T02:00:57.547 に答える
-2

C#での型推論は、短い書き込みのために悪用されるため、好きではありません。もちろん、これは非常に優れた機能ですが、この場合のように、人々はそれを私見で悪用します。

この場合、タイプに関する混乱を避けるために、タイプを明示的に指定します(つまり、42は長いか、バイトか短いか)。

だから、ほんの数行で実装できる単純なタプルクラスを持ってみませんか。また、怠惰な場合は、タプルクラスの拡張メソッドを作成することもできます。これにより、生活が楽になりますが、よりクリーンになります。

提示した一般的なタプルクラスの代わりに「ファンシー」タプルクラスを使用することのポイントを理解しないでください(型推論を除く)。

于 2009-11-30T22:07:39.673 に答える