2008年1月26日土曜日

Dictionary<TKey, TValue>とIEquatable<T>

ある意味当たり前ですが、気づかずにはまってしまいました。
Dictionary<TKey,TValue>はIEquatable<T>が実装されていればそれを使って比較してくれます。Object.Equals()と違って型保証されているので便利に使っていました。
しかし、Dictionary<TKey,TValue>はTKeyを比較する前にまずハッシュします。この際、IEquatable<T>の有無にかかわらずObject.GetHashCode()を使います。つまり、このハッシュ値が異なるTKeyはIEquatable<T>.Equals()が呼び出されることなく異なる値として扱われてしまいます。
むーん。

2008年1月7日月曜日

ILogicalThreadAffinativeとThread Local Storage

TLSつまりThread Local Storageは便利で、コンテキスト情報を持たせるときに活用しようとずっと考えていました。すでにある例としてはIPrincipalでしょうか。Threadにプリンシパルを持たせることで、実行に必要な権限があるかをいつでもテストできます。
ですがこれ、Thread Localということは当然Threadをまたぐことができません。.NETでは簡単に非同期処理などを利用でき複数Threadにまたがってしまう。そうなったときTLSは使えません。

そこで自分の生成した子スレッドにのみ引き継がれる都合のいいTLSはないかと.NETクラスライブラリを調べていましたがなかなか出合えませんでした。
が、やはり根気よく調べればありました。それがILogicalThreadAffinativeです。このinterfaceはメンバがありません。ただ継承すればそれだけでTLSの内容が子スレッドにも引き継がれるようになります。
日本語圏でググったところ、まだあまり使われていないようですが、これはかなり使えます。

??演算子

C#で??演算子というものを見つけました。調べたところ、C# 2.0、つまりVS2005からあったそうで、ずっと気づいていませんでした。

a = b ?? c;
a = b != null ? b : c;
とほぼ等価です。違うのは、bが1回しか評価されないことです。Perlの||的な動きをすると言えばいいでしょうか。