System.Uri クラスに残念な思いをいたしました
2003年1月10日(金曜日)
System.Uri クラスに残念な思いをいたしました
.NET Framework の System.Uri クラスは URI を扱うことが出来るのですが、このクラスにはいろいろと困るところがあります。
- 一致演算子がオーバーライドされていない。同じ URI を参照する Uri を比較して false になるというのは、ちょっと違和感があります。
- Equals() メソッドの動作。Equals() はオーバーライドされていて、同じ URI なら true になります。しかし、フラグメント ID が異なっていても結果が true になったりするので、やや予想とは異なる結果になります。
- URL エンコードの動作が一貫性に欠けている。dontEscape が true の場合、"%20" は "%20" のままで問題ありません。しかし、dontEscape が false ならば "%20" は "%2520" にエンコードされなければおかしいでしょう。実際には、妙な気を利かせて %HH 形式の物はスルーしてしまいます。
- クエリストリングとフラグメント ID を持つ URI の処理がおかしい。Uri のコンストラクタに、たとえば http://example.com?foo#bar のような URI を渡すと、なんと # が %23 にエンコードされてしまいます。これはバグだと思うのですが……。
- MakeRelative() の動作に一部おかしいところがある。たとえば、http://example.com/foo?bar から http://example.com/foo?baz を参照する相対 URI は、"foo?baz" ではなく "" (空文字列) になってしまいます。http://example.com/foo から http://example.com/ を参照する相対 URI は、"./" ではなく "" (空文字列) になります。どう考えてもおかしいでしょう。
とりわけひどいのは MakeRelative() の動作です。Uri クラスの MakeRelative() メソッドで相対 URI を作るルーチンでは、クエリストリングを持つ CGI は全く扱えないわけです。
そんなわけで、System.Uri を継承してダメなメソッドや演算子を上書きする Bakera.Url クラスを作成したりしました。名前が微妙ですが、Bakera.Uri にしてしまうと単に Uri と書いたときにどちらを指すか分かりませんし (分からないと言われてコンパイルできないはず)、そもそも System.Uri は URN を扱えるというわけでもないので。
- 「System.Uri クラスに残念な思いをいたしました」にコメントを書く
- 前(古い): Red Hat Network
- 次(新しい): System.Uri と System.Web.HttpUtility