[解決済み] なぜList<T>を継承しないのですか?
質問
番組の企画を考えるとき、私はよく次のような思考の連鎖からスタートします。
<ブロッククオートアメフトチームは、アメフト選手のリストに過ぎない。したがって、私はそれを表現する必要があります。
var football_team = new List<FootballPlayer>();
このリストの順番は、ロスターに記載されている選手の順番を表しています。
しかし、チームには単なる選手のリスト以外にも、記録しなければならないプロパティがあることに後で気づきました。例えば、今シーズンの得点の累計、現在の予算、ユニフォームの色、そして
string
チーム名を表すなど。
では、考えます。
さて、サッカーチームは選手のリストと同じですが、さらに、名前(a
string
)、得点の累計(int
). .NETにはサッカーチームを格納するクラスがないので、自分でクラスを作ることにします。最も似ていて関連性のある既存の構造はList<FootballPlayer>
ということで、それを継承することにします。class FootballTeam : List<FootballPlayer> { public string TeamName; public int RunningTotal }
しかし、それが判明したのは
を継承してはいけないというガイドラインがあります。
List<T>
. 私は2つの点でこのガイドラインに徹底的に困惑しています。
なぜダメなのか?
どうやら
List
は、何らかの形でパフォーマンスに最適化されています。
. どのように?を拡張した場合、どのようなパフォーマンスの問題が発生するのでしょうか?
List
? 具体的に何が壊れるのでしょうか?
もう一つの理由は、私が見たところ
List
はマイクロソフトが提供するものであり、私にはコントロールできないので
公開APIを公開した後では、後から変更することはできません。
. しかし、これを理解するのに苦労しています。パブリックAPIとは何なのか、なぜ気にしなければならないのか。もし私の現在のプロジェクトがこのパブリックAPIを持たず、今後も持つ可能性がないのであれば、このガイドラインを無視して大丈夫なのでしょうか?もし私が
List
と
公開APIが必要なことがわかりましたが、どのような困難があるのでしょうか?
なぜそれが重要なのか?リストはリストです。何が変わる可能性があるのか?何を変えたいと思うことがあるのでしょうか?
そして最後に、もしマイクロソフトが私に
List
なぜ
sealed
?
他に何を使えばいいのでしょうか?
どうやらカスタムコレクションのために、マイクロソフトが提供する
Collection
クラスの代わりに拡張する必要があります。
List
. しかし、このクラスは非常に素っ気なく、あまり便利なものは持っていません。
のような
AddRange
, 例えば
jvitor83の回答
は、その特定の方法に対するパフォーマンスの根拠を提供していますが、どのように遅い
AddRange
がないよりはましですが
AddRange
?
を継承しています。
Collection
を継承するよりもはるかに多くの作業を必要とします。
List
そして、何のメリットもありません。確かにマイクロソフトは意味もなく余計なことをしろとは言わないでしょうから、何か誤解しているような気がしてなりません。
Collection
は、実は私の問題に対する正しい解決策ではないのです。
を実装するなどの提案を見たことがあります。
IList
. ただ、ダメなんです。これは何十行もの定型的なコードで、私には何の得にもなりません。
最後に
List
を何かで囲む。
class FootballTeam
{
public List<FootballPlayer> Players;
}
これには2つの問題があります。
-
コードが無駄に冗長になる。私は今
my_team.Players.Count
ではなく、単にmy_team.Count
. ありがたいことに、C#ではインデックスの作成を透過的にするためにインデクサを定義し、内部のList
... しかし、それは多くのコードです しかし、これは多くのコードです!私はその仕事のために何を得るのでしょうか? -
ただ、意味がないんです。サッカーチームは選手のリストを持っていません。それは は 選手のリストです。John McFootballer has joined SomeTeam's players"とは言わないんですね。あなたは、"John has joined SomeTeam"と言っています。文字列の文字に文字を追加するのではなく、文字列に文字を追加するのです。図書館の本に本を追加するのではなく、図書館に本を追加するのです。
しかし、これは非常に直感的でない考え方だと思います。
私の質問(要約)
論理的に(つまり、人間の心にとって)単なるデータ構造であるデータ構造を表現する正しいC#の方法は何ですか?
list
の
things
を、少しベルとホイッスルを使って?
を継承しているのでしょうか?
List<T>
常に受け入れられないのでしょうか?どのような場合に受け入れられますか?なぜ/なぜダメなのか?を継承するかどうかを決めるとき、プログラマは何を考慮しなければならないか?
List<T>
を使うかどうか?
どのように解決するのですか?
良い回答がいくつかありますね。私はそれらに以下の点を付け加えたいと思います。
<ブロッククオート論理的には(つまり、人間の心にとっては)単なるリストであるデータ構造を、C#で正しく表現する方法は何でしょうか。
サッカーの存在を知っている、コンピューター・プログラマーではない10人に、空欄を埋めるように尋ねてみてください。
<ブロッククオートサッカーチームは、特定の種類の_____である。
した。 だれでも それとも、全員が「スポーツチーム」「クラブ」「組織」と言ったのでしょうか? アメフトチームが 特定の種類の選手のリスト は、あなたの人間の頭の中にあるものであり、あなたの人間の頭の中だけのものです。
List<T>
は
機構
. サッカーチームは
ビジネスオブジェクト
-- にある何らかの概念を表すオブジェクトです。
ビジネスドメイン
プログラムの 混ぜるな危険! サッカーチーム
は、一種の
チーム; それは
を持っています。
ロスター、名簿
は、選手のリスト
. ロスターは
特定の種類の選手リスト
. ロスター
は
選手のリストです。というプロパティを作って
Roster
というのは
List<Player>
. そして、それを
ReadOnlyList<Player>
ただし、サッカーチームについて知っている人なら誰でも、登録選手から選手を削除することができると考えている場合は除きます。
を継承しているのか?
List<T>
は、常に受け入れられないのでしょうか?
誰にとって受け入れ難いか?私?
どのような場合に受け入れられるのでしょうか?
という仕組みを作る場合
を拡張します。
List<T>
機構
.
を継承するかどうかを決定するとき、プログラマは何を考慮しなければならないか?
List<T>
それとも
を作っているのでしょうか? 機構 または ビジネスオブジェクト ?
でも、これだけのコードがあるんですよ! でも、これだけのコードを書いてどうなるんだ?
の関連するメンバに転送するメソッドを書くのにかかる時間よりも、質問をタイプするのにかかる時間の方が長いのです。
List<T>
を50回繰り返す。あなたは明らかに冗長性を恐れていませんし、ここで話しているのはごくわずかなコードのことです。
アップデイト
さらに考えてみたところ、サッカーチームを選手のリストとしてモデル化しないほうがいい理由がもうひとつありました。実際、フットボールチームを 有する のリストもあります。チームを選手のリストと見なす/持つことの問題は、あなたが得たものが スナップショット チームの ある時点の . このクラスのビジネスケースがどのようなものか知りませんが、もし私がフットボールチームを代表するクラスを持っていたら、「2003年から2013年の間に何人のシーホークスの選手が怪我で試合に出られなかったか」「以前他のチームでプレーしていたデンバーの選手で、前年比で最も走行ヤードが増加したのは誰か」といった質問をしたいところです。 今年のピガーは全勝だったのか? "。
つまり、サッカーチームというのは、よくモデル化されているように思います。 歴史的事実の集合体 例えば、選手がいつ採用されたか、負傷したか、引退したか、など。もちろん、現在の選手名簿は重要な事実であり、前面に押し出すべきものですが、このオブジェクトでやりたいことの中には、もっと歴史的な視点が必要なものがあるかもしれません。
関連
-
[解決済み] リストのリストからフラットなリストを作るには?
-
[解決済み] リスト内のアイテムのインデックスを検索する
-
[解決済み] リストが空かどうかを確認するにはどうすればよいですか?
-
[解決済み] Pythonのリストメソッドであるappendとextendの違いは何ですか?
-
[解決済み] 割り当て後にリストが予期せず変更されました。その理由と防止策を教えてください。
-
[解決済み] リストの最後の要素を取得する方法
-
[解決済み] リストからランダムに項目を選択するにはどうすればよいですか?
-
[解決済み] なぜlist.join(string)ではなくstring.join(list)なのでしょうか?
-
[解決済み] Pythonのクラスはなぜオブジェクトを継承するのですか?
-
[解決済み] mixinとは何か、なぜ有用なのか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】文字列が有効な DateTime " format dd/MM/yyyy " として認識されなかった。
-
[解決済み】取り消せないメンバはメソッドのように使えない?
-
[解決済み】なぜこのコードはInvalidOperationExceptionを投げるのですか?
-
[解決済み】Visual Studio: 操作を完了できませんでした。パラメータが正しくありません
-
[解決済み】2つ(またはそれ以上)のリストを1つに統合する(C# .NETで
-
[解決済み】パラメータ付きRedirectToAction
-
[解決済み】IntPtrとは一体何なのか?
-
[解決済み】別のスレッドがこのオブジェクトを所有しているため、呼び出し側のスレッドはこのオブジェクトにアクセスできない
-
[解決済み] List<T> または IList<T> [終了しました]。
-
[解決済み】汝、std::vector を継承してはならない。