2004-05-19 (Wed) [長年日記]
_ NotSupportedException クラス
.NET Frameworkを使っていると、ちょくちょくこの例外にお目にかかる。
たとえば、Stream.Length プロパティとか。
NotSupportedException Stream から派生したクラスがシークをサポートしていません。
[Stream.Length プロパティより引用]
つまり、StreamのサブクラスでもLengthが実装されてないかもしれないということだ。 こんな設計にされたら、せっかくの静的な型チェックも意味がない。
LengthをStreamから他のクラスに移さないのには何か深遠な理由があるのだろうか。
こんにちは。C#のヘジルスバーグはDelphiの設計者でもあったので、VCLのTStreamに似てるのではないでしょうか。TStreamにもPositionやSizeという、デフォルトでは意味のないプロパティがあります。(TWinSocketStreamでは使ってないはず。美しくない)
なるほど。<br>でもどうしてTStreamはそういう設計だったんでしょうね。<br>弱い型の言語のライブラリを参考にしたからとか?
うーん、わかりません。ただ、最初の頃は TStream の継承クラスはシークできるものばかりだったので(TFileStream, TMemoryStream, TBlobStream)、歴史的経緯でそうなったのだと思っていました。でも、それだと.Netもそうなってる理由にならないですね・・・
んー、OSその物がそうなので、という事では。<br>Socketを ReadFile / WriteFile でアクセスできるけど、PositionやLengthを設定できないのと同様に。<br>プロパティで出ているCanSeekを見るとLengthを得られるかという意味とほぼ同等に使える値が取れます。
JXTA (のJava実装) でも、同じようなフラストレーションを味わったなあ>NotSupportedException<br><br>> せっかくの静的なチェックも(略)<br><br>同感。
んー、下のレイヤーに不都合があっても、できるだけそれを隠蔽するのがよいライブラリなんじゃないでしょうか。<br>CanSeekについては、結局動的なチェックになってしまうので、<br>NotSupportedExceptionを捕捉するのと大差ないと思います。
> 同感。<br><br>やっぱそうですよねえ。<br><br>ちなみにshudoさんは私とは別人です。まぎらわしくてすみません。
>んー、下のレイヤーに不都合があっても、できるだけそれを隠蔽するのがよいライブラリなんじゃないでしょうか。 <br><br> 良いって基準は色々あるけど。<br> 妥協点の違いにすぎませんが、Readモードで開いたのにWriteがあるほうがはるかに問題ですよね。<br> そう考えてコンパイラでの型強制を考えて理想的にクラスライブラリを構築するとは Read / Write の一方づつ、両方、シーク有り無し、Length取得可能不可能でマトリックス的に用意するって事でしょうか。<br> 私的には、そういうライブラリが実在したら使い分けが面倒で融通の利かないクラスばかりが揃った嫌なライブラリに思います。
菊池さんがそういう(クラスが細分化された)ライブラリをお好きでないというのは理解できる部分もあるのですが(Rubyのライブラリもなるべく単一のクラスで色々な機能を提供する傾向がありますし)、私としてはやはり静的な型を持つ言語の利点を生かすためにはそういうライブラリの方が好もしいと思います。<br>ただ、C#の場合は実装の多重継承がないので、ライブラリの実装者にとっては大変な面もあると思いますが。