web-dev-qa-db-ja.com

KeyValuePairのような事前に作成された構造に対して2プロパティクラスをいつ使用する必要がありますか?

KeyValuePairTupleなどの事前に作成されたジェネリック構造を使用する代わりに、Key/Valueタイプのデータを独自のクラスに配置する必要があるのはいつですか。

たとえば、私が作成するほとんどのComboBoxにはDisplayNameとValueが含まれています。これは、新しいクラスに配置するタイミングと、KeyValuePairを使用するタイミングを決定しようとしている種類のデータです。

私は現在iCalendarを使用するものに取り組んでおり、選択したユーザーのデータは最終的にkey1=value1;key2=value2;タイプの文字列に結合されます。データをKeyValuePair<string,string>に入れることから始めましたが、今はそれが独自のクラスであるのかどうか疑問に思っています。

全体として、2プロパティオブジェクトに対してKeyValuePairのような既存の構造体/クラスを使用することを決定するときに使用されるガイドライン、およびどのような状況で2つのプロパティオブジェクトを使用するかを調べることに興味があります。

31
Rachel

通常、ほとんどの場合、KeyValuePairやTupleではなくオブジェクトを使用します。まず、6か月後に変更を加える場合、何を考えているよりも、以前の意図を理解する方がはるかに簡単ですTuple tであり、なぜそれがそれらの面白い値を持っているかです。第二に、物事が成長し、変化するにつれて、必要に応じて単純なデータ転送オブジェクトの動作を簡単に与えることができます。 2つの名前形式が必要ですか?簡単です。適切なToString()オーバーロードを追加するだけです。インターフェースを実装するために必要ですか?問題ない。最後に、特に自動プロパティとコード補完を使用して、単純なオブジェクトを作成するオーバーヘッドはほとんどゼロです。

ボーナスProtip:これらのオブジェクトが名前空間を汚染しないようにしたい場合、クラス内にプライベートクラスを作成することは、物事をラップの下に保ち、奇妙な依存関係を防ぐための優れた方法です。

27
Wyatt Barnett

新しいクラスを定義するためのルールは単純です。「Occamのかみそり」によって要約されています。

http://c2.com/cgi/wiki?OccamsRazor

正当な理由がない限り、新しいクラスを導入しないでください。または、ビルド済みのクラスをできるだけ使用します。または、できるだけ少ないものを発明します。しかし、あなたはより少ないコードを書くことに慣れています。

オブジェクトに一意の責任を割り当てる必要があり、その責任が事前作成クラスで定義されていない場合は、事前作成クラスを使用できません。多くの場合、これはユニークな方法です。

TupleまたはKeyValuePairが推奨されます。

まで。

A TupleまたはKeyValuePairの一部ではない機能が必要です。次に、独自のクラスを定義する必要があります。

7
S.Lott

独自のクラスを作成する場合、2つの値が何であるかに関するドキュメントを配置する明確な場所があります。特に、2つの文字列は明確な定義ではないためです。しかし、あなたは次のようなものを書くことができます

 public class MyPair : Tuple<string, string>
4
Sign

S.Lottが書いた

正当な理由がない限り、新しいクラスを導入しないでください。または、ビルド済みのクラスをできるだけ使用します。できる限り発明しない。

事前構築されたクラスで定義されていないオブジェクトに一意の責任を割り当てる必要がある場合は、事前構築されたクラスを使用できません。

なぜ私がこれに関して深刻な問題を抱えているのかを述べさせてください。以来

KeyValuePair [string、string]

大丈夫そうです.... KeyValue [string、KeyValue [string、KeyValuePair [string、string]]]も大丈夫ですか? S.Lottがこれに対して何を言うかわかりませんが、上司はそれを大丈夫だと思っています。

あえて反対する。そして、ここに理由があります:それは続くコードの可読性を減らします。このようなデータ構造を埋める関数は、はるかに複雑になり、エラー(エラー..例外)が発生しやすくなります(少なくとも some ビジネスロジックも想像してみてください)。私は上司とあまり議論しませんでしたが、ここでそれを言います。読みやすさは、わずかなスペースの節約に勝ります(これは his 引数でした)。したがって、いくつかのフィールドがあるクラスオブジェクトではないでしょう。しかし、いくつかは時々空のままですより良いですか?

追伸私はUltra_Noobです。間違っているかどうか教えてください。

4
Chani

key/valueペアと言うとき、私は通常ハッシュテーブル、または連想配列、または単にKeyValuePairと考えます=オブジェクト。私はそれらすべてを使用しており、どちらを使用しても違いはありません。

キーと値のペアのリストについて最も重要なことは、keysは一意である必要があり(結局のところ、それがキーであるため)、前述のすべての構造が実際にその機能を提供するということです。

それ以外は、キーで検索したり、プッシュやポップなどのリスト(配列)スタイルのアクションを実行したりします。

だから、私の答えは[〜#〜] no [〜#〜]であり、多くの組み込み構造がすでにそれを行っているため、キー/値ペアのオブジェクトを明示的に作成しません私。

3
Saeed Neamati

クリーンコード の第6章には、データ構造とクラスのどちらを使用するかについての適切な説明があります。簡単に言えば、データを操作するための新しい関数の追加がほとんど予想される場合は、データ構造を使用します。クラスを使用するのは、既存の関数で操作する新しいデータ型を追加することがほとんどの場合です。 ComboBoxは後者の例です。多くの異なるデータ型(異なるウィジェットには異なる種類のデータ)を操作する関数のセット(ComboBox実装)があります。

3
Karl Bielefeldt

私はおそらく Wilding here に同意しますが、私はこの種のことについても少し初心者です。

組み込み型はしばしばmechanismオブジェクトであることが推奨されます。たとえば、KeyValuePairは、ディクショナリとハッシュテーブルのメカニズムの一部であり、一意のキーを保証するのに役立ち、メカニズム自体のコンテキスト内で意味のある名前を持つプロパティを持っています。

一方、カスタムメイドのデータオブジェクトを使用すると、データのより良い表現が提供され、多くの読みやすさと拡張性を含む利点。カスタムビルドオブジェクトで既存のコードを サイン推奨 として再利用するのをやめることは何もありませんが、ラップされたクラスを非表示にして 抽象化リーク を避け、変更できるようにします残りのコードに影響を与えることなく、後で基礎となる実装。

だから本当の質問:あなたはデータを表現していますか、それともメカニズムでデータを使用していますか?(そしてこれらの概念を一緒に混ぜることはお勧めしません).

私の経験では、Tuple [string、string]がメソッドに渡され、Item1とItem2が何であるかをすぐに知る方法がないことは何より悪いことではありません。メソッド内で、またはクラスのプライベートメンバーとしてのみタプルを使用するのが最適です。

2
Ben