2018年3月24日土曜日

ListView Extensions ver.1.0.1リリース

ListView Extensions ver.1.0.1をリリースしました。
NuGet Gallery | ListViewExtensions 1.0.1
変更点は以下の2点です。
  • Obsoleteに指定していた非同期アクセス非サポートのクラスを削除した
  • SyncedObservableCollection<T>が実装する非ジェネリックインターフェイス(IList, ICollectionなど)を明示的なインターフェイスの実装にした
どちらも破壊的な変更ですので、今までコンパイルが通っていたコードがアップデートによって通らなくなる可能性があります。ただ、その影響範囲は小さいはずです。
そもそもこの変更でコンパイルが通らなくなるようなコードは悪いコードなので悔い改めてください。


ところで、「明示的なインターフェイスの実装(explicit interface implementation)」 というC#の機能、しっかり知りませんでした…。恥ずかしい///
明示的なインターフェイスの実装 (C# プログラミング ガイド)
このような機能が必要になる状況として、上記のサイトでは、同じシグネチャのメソッドを持っている別々のインターフェイスを両方とも実装するクラスで、それぞれ別々の実装を行いたいときというのが説明されています。
それはそれで納得はいくのですが、どちらかと言えば今回重要になってくるのはこの機能の副作用?です。

明示的なインターフェイスの実装では、インスタンスをそれぞれのインターフェイスにキャストしない限りそれぞれのメソッドにアクセスできないという制約が発生します。当然ですね、別々の実装があるのですから、呼び出し時にはそれを絞り込むための制約が必要です。
これを活用することで、別にシグネチャが重複していなくても、IListやICollectionなどの非ジェネリックメソッドを積極的には呼び出して欲しくないときに、非ジェネリックインターフェイスを明示的に実装することで、呼び出し側も非ジェネリックインターフェイスにキャストしないと呼び出せなくすることができます。
例えば、List<T>が非ジェネリックのIListも実装しているにもかかわらず、Visual StudioのIntelliSenseに非ジェネリックメソッドが出てこないのはこういうことだったのですね。

ちなみに、明示的なインターフェイスの実装ではアクセス修飾子(publicなど)は付けられません。明示的なインターフェイスの実装である時点でインターフェイスの実装だというのがわかっているので自動的にpublicになるようです。
通常、クラスではアクセス修飾子を省略するとprivateになるのでちょっと違和感はありますね。

話がだいぶそれてしまいましたが、この点を修正したListView Extensions 1.0.1をよろしくお願いします。