Out of Memory

本ブログは更新を停止しました。Aerieをよろしくお願いいたします。

目次

Blog 利用状況

ニュース

2009年3月31日
更新を停止しました。引き続きAerieを御愛顧くださいませ。
2009年2月3日
原則としてコメント受付を停止しました。コメントはAerieまでお願いいたします。
詳細は2月3日のエントリをご覧ください。
2008年7月1日
Microsoft MVP for Developer Tools - Visual C++ を再受賞しました。
2008年2月某日
MVPアワードがVisual C++に変更になりました。
2007年10月23日
blogタイトルを変更しました。
2007年7月1日
Microsoft MVP for Windows - SDKを受賞しました!
2007年6月20日
スキル「ニュース欄ハック」を覚えた!
2006年12月14日
記念すべき初エントリ
2006年12月3日
わんくま同盟に加盟しました。

カレンダー

中の人

αετο? / aetos / あえとす

シャノン? 誰それ。

顔写真

埼玉を馬鹿にする奴は俺が許さん。

基本的に知ったかぶり。興味を持った技術に手を出して、ちょっと齧りはするものの、それを応用して何か形にするまでは及ばずに飽きて放り出す人。

書庫

日記カテゴリ

インターフェイスの要件は最小であるべきか?

なんだかぱっとしないタイトル。
ここで言う「インターフェイス」とは、多重継承できるあの interface じゃなくて、もっと一般的な意味でのそれです。約束事、みたいな。

例えば、メソッドの引数に何かコレクションを受け取るとして、その型はどう宣言すべきか、と。
IEnumerable<T> か、ICollection<T> か、IList<T> か、はたまた T[] か。

極めて単純無思考には T[] 。
しかし、T[] のほとんどの特性は IList<T> も備えているため、俺は個人的に IList<T> を好む傾向にある。
多次元配列なんかは、もはや配列をそのまんま使うんじゃなくて、何らかのクラスを作ったほうがいいと思う。

しかし、ランダムアクセスの必要が無ければ、IEnumerable<T> でも十分ではある。
そういう時、IEnumerable<T> とすべきか否か。

ちょっと引っかかるのは、ICollection<T> や IList<T> は無限リストを許容しないが、IEnumerable<T> は許容するというところ。
ということは、IEnumerable<T> を引数に取るメソッドは、すべからく無限リストに対応すべし、ということになるか?
遅延処理を意図したロジックならいいが、そうでない場合もあるだろう。
IEnumerable<T>.Count() なんかは ICollection<T>.Count でもよかったんじゃないだろうか。無限リストに使ったらオーバーフローしたぞ。
まぁ、ICollection<T> や IList<T> を受け取ったとして、要素数が Int32.MaxValue 個ある場合にちゃんと処理できなければならない、というのもなかなか酷ではあるのだが。

また、これは感覚的な問題でもあるが、用途としては IEnumerable<T> で十分であっても、IList<T> を使いたいという心情もあると思う。
ちょっと前の var 論争でもあった意見だが、「IEnumerable<T> ではコレクションのような気がしない。IList<T> ならコレクションであるという意図が込められる」みたいな。

また別問題ではあるが、独自のデータ構造を作るか否かという問題もある。
例えば、Pair<T, U> という既存の型があった場合、あらゆる2値の組み合わせは Pair<T, U> で事足りるか、ということ。
Pair<T, U> は、それぞれの値の意味を理解しないので、.First とか .Second とかいうメンバ名にならざるを得ない。
人の名前を表すのに、FirstName と LastName というメンバを持つクラスを作るか、Pair<string, string> で済ませるか、とか。
独自のデータ型を作らずに既存の型を最大限活用した場合、

  • メンバの意味がわかりにくくなる
  • ジェネリックの入れ子が深くなる

という問題が発生するわけだが、どうよ? という。

投稿日時 : 2008年7月17日 16:05

Feedback

# re: インターフェイスの要件は最小であるべきか? 2008/07/17 16:20 Hirotow

IListになっているとyieldとか使えないので、
単純にコレクションを受け取る場合、基本的にIEnumeratableを受け取り内部でforeachなりList<T>.AddRange()なりするようにすべきだと思っています。
逆に、データバインドなどデータの静的有限性が必要とされる場合はIListのみとする設計が正しいでしょう。
という個人的意見。

# re: インターフェイスの要件は最小であるべきか? 2008/07/17 16:37 NyaRuRu

>しかし、ランダムアクセスの必要が無ければ、IEnumerable<T> でも十分ではある。

これだと LINQ がすっきり説明できないんですよね.
LINQ では,Haskell で言うところの型クラスのように generic interface を使っています.
既存の型から,ある特定の性質を付与された新しい型を導出するために generic interface を使う,で通じればいいんですが.
その辺のもやもやについては,以下で書きましたのでどうぞ.
http://d.hatena.ne.jp/NyaRuRu/20080313/p1

うーむ,なんかこう,型総称性が入る前に広まったデザインパターンから外れている“パターン”の説明って大変ですな.
その意味ではデザインパターン偉大なのか.

# re: インターフェイスの要件は最小であるべきか? 2008/07/17 16:55 シャノン

> IListになっているとyieldとか使えないので、

逆に、IEnumerable になっていると Count や添え字アクセスが使えません。
とりあえずは必要なかったけど、後になってそれらが必要になった、なんて時はどうしましょう?
「IList にしておくと後で困る」ということはあまり無いような気がします。

> 逆に、データバインドなどデータの静的有限性が必要とされる場合はIListのみとする設計が正しいでしょう。

実は ASP.NET のデータバインドは IEnumerable を許容します。

> その辺のもやもやについては,以下で書きましたのでどうぞ.

俺はクエリ構文も嫌いなんですが、なんで嫌いかというと、まさにそこで言う「ミニモード」「言語内ミニ言語」が嫌いだからです。
拡張メソッド構文はたまに使うけど、そういう、思想の違うものが混ざってくると、俺の場合「ゾーン」を抜けちゃうんですよ。

だから、C# もいっぺん再設計してみたらどうなの? って声も出てくるわけで。

# re: インターフェイスの要件は最小であるべきか? 2008/07/17 16:58 シャノン

あぁ、言い忘れた。
IEnumerable は例であって、他のインターフェイスであっても成立する話として受け止めてください。

# re: インターフェイスの要件は最小であるべきか? 2008/07/17 17:34 NyaRuRu

>まさにそこで言う「ミニモード」「言語内ミニ言語」が嫌いだからです。

なるほど.
私の場合,色々な言語を見て回って C# に戻ってきたせいで,今まで当たり前に思えてきたコードも単なる「ミニモード」に見えるようになってしまいました.
連続するガード句,if else の連鎖,条件演算子 ( c ? a : b ) の連鎖,for ループ,while (true), switch case など,私にとってはただの「言語内ミニ言語」です.

最近は,コードに for ループや while (true) が混ざっていると「ゾーン」を抜けちゃったり.
もっとも,だったら最初から「for や while が最初から意図的に使いにくくされた言語でやれ」という意見も,分からなくはないですが.

# re: インターフェイスの要件は最小であるべきか? 2008/07/17 19:17 Hirotow

>とりあえずは必要なかったけど、後になってそれらが必要になった、なんて時はどうしましょう?
メソッドの先頭でList<T>にAddRangeする。

>実は ASP.NET のデータバインドは IEnumerable を許容します。
(;゚Д゚)(゚Д゚;(゚Д゚;)ナ、ナンダッテー!!

# re: インターフェイスの要件は最小であるべきか? 2008/07/17 20:19 ネタ好き未記入

C#はもともと型重視のオブジェクト指向だから、型名という情報を軽視してはならないと思います。
ですから私は新しい型を作るべきだと思います。

# re: インターフェイスの要件は最小であるべきか? 2008/07/17 20:20 シャノン

んー…
yield が使えないのは、戻り値の場合ですよね。

…まぁいいか。
AddRange すりゃ IList が手に入るってんなら。

# re: インターフェイスの要件は最小であるべきか? 2008/07/17 20:24 NyaRuRu

>俺はクエリ構文も嫌いなんですが、なんで嫌いかというと、まさにそこで言う「ミニモード」「言語内ミニ言語」が嫌いだからです。
>拡張メソッド構文はたまに使うけど、そういう、思想の違うものが混ざってくると、俺の場合「ゾーン」を抜けちゃうんですよ。

ちなみに,シャノンさんの言われていることはよく分かります.
私自身,ここでシャノンさんが言われているのと同じ理由で,「C++ のソースコード中に現われる正規表現」が大嫌いでしたから.

結局その後考え方を変えましたが.
いまはなるべく大きな問題を小さな問題に分割し,分解された問題ごとに適切な計算モデルを選択する方を選ぶよう心がけています.問題に対して正規表現が最適と思うなら,まずは正規表現で解き方を考えます.
もちろん言語やプラットフォームの都合上,思い付いた最適な計算モデルが採用できないこともありますが,その場合もまずは最適な計算モデルで解けるかどうか考えます.そして解き方が分かったら,その解き方を利用可能な計算モデルに翻訳する形で,実装を得るようにしています.

# re: インターフェイスの要件は最小であるべきか? 2008/07/17 20:42 シャノン

> 私は新しい型を作るべきだと思います。

基本はそうだと思いますが、限度もあります。
正直、EventArgs<T> なんてのは活用したいですし、年齢と身長と体重をすべて int ではなくそれぞれ専用の型を作るのかというと、そういうことはないでしょう。

リネーム機構が欲しいなぁ。

using Name = Pair< string, string >
{
 FirstName = First,
 LastName = Second
};

みたいな?

# re: インターフェイスの要件は最小であるべきか? 2008/07/17 20:46 シャノン

> C++ のソースコード中に現われる正規表現

まぁ、あれもミニ言語と言えばミニ言語か。
個人的にはあまり違和感ないです。正規表現が文字列なら。
JavaScript の、/hoge/i みたいなのは嫌。
でも、あれはあれで \ を書くときに二重にエスケープしなくていいからステキではあるのよね。

> いまはなるべく大きな問題を小さな問題に分割し,分解された問題ごとに適切な計算モデルを選択する方を選ぶよう心がけています

もちろん、それに反対するものではありません。
なんか嫌なのは、書き方とか思想が根本的に違うものが混ぜ書きされていること。
例えば、C#アプリの中にあるXAMLファイルのように、ソースファイルが違えば気にならない程度のものでしかないのかもしれません。
あ、VB のあれは嫌ですね。
Dim x = <Hoge><Hage><Hige/></Hage></Hoge>

# re: インターフェイスの要件は最小であるべきか? 2009/07/22 23:04 akira

T[]かList<T>かについては、javaについていえば、List<T>がいいです。Effective Javaに理由が書いてあります。T[]は共変です。つまり、A extends Bならば、A[] extends B[]です。

私は、あまり多くのインターフェイスがあるクラスは何か気持ち悪い気がします。どこまで自己主張してんだと。何もしないくせに、いっぱいやってるように見せかけるやつっていうのは、現実社会でも鬱陶しいですよね。

# モンクレール ダウン アウトレット 2012/11/08 7:22 http://moncler.katsu-ie.com/

匿名なのに、私には誰だか分かる・・・(^_^;)ありがとう。。。

タイトル
名前
Url
コメント