質問

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. リストやタプルのようなものではなく、特定の型を作成するのが理にかなっているのはどの時点(はい、私のために一般化する)ですか? (経験則を探しています)

役に立ちましたか?

解決

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

var itemsWithChildCounts 
    = myObjects.Select(x => new { Name = x.Name, Count = x.Children.Count() });

他のヒント

Bill Wagnerの Visual Studio Magazine のrel = "noreferrer">記事

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
}

1-2の場合:独自のタプルクラスを実装することを好みます。あなたが盗んだ実装はまともなものです。うまくいくはずです。

3:経験則です-この機能を複数のメソッド(同じタイプの同じ意味を持つ)で再利用するか、パブリックAPIで使用する場合は、 「本物」を実装する時間特定のタイプのクラス。

  1. 「クラスの実装」メソッドは取得するのと同じくらい良好です(とにかく.NETの次のバージョンにある必要があります)
  2. わからない。今のところ、自分のクラスの個人ライブラリに保存している。
  3. 公開されたらすぐに適切なクラスを作成することを検討します(つまり、クラスの関連する値を内部的に保存するためだけに使用されなくなったとき)。

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

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

新しい値セットをプログラムに導入することが理にかなっている場合は、新しい型を作成することをお勧めします。たとえば、複雑な計算機を作成している場合は、複素数型を作成します。本当に「接着」したいだけなら少しの間、いくつかの変数を一緒に使用する場合は、おそらくタプルの方が適しています。コンソールから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 ++では、戻り値が参照型である場合に関数呼び出しを代入演算子の左オペランドにできるという事実を利用して、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に戻すために、示されているように確かに汎用タプルクラスを作成できますが、&quot; unpack&quot;と結び付けるような関数を作成できます。 C#のタプル?私はそれを試していない、楽しいように聞こえます。そのようなものがなければ、私はC#タプルライブラリをコードで増殖させることを嫌がります。

C#での型推論は、短文を書くために酷使されるため、好きではありません。もちろん、これは非常に便利な機能ですが、この場合のように、人々はそれを乱用しています。

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

では、数行で実装できる単純なタプルクラスがないのはなぜですか。怠け者の場合は、タプルクラスの拡張メソッドを作成することもできます。これにより、作業が楽になりますが、よりクリーンになります。

「空想」を持っていることのポイントを見ないでください。提示した一般的なクラスの代わりにタプルクラス(型推論を除く)。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top