自己参照(「再帰的」)タイプのパラメーター制約を追加することにより、単純なインターフェースをより複雑にすることがよくあります。たとえば、私はこれを変えるかもしれません:
interface ICloneable
{
ICloneable Clone();
}
class Sheep : ICloneable
{
ICloneable Clone() { … }
} //^^^^^^^^^^
Sheep dolly = new Sheep().Clone() as Sheep;
//^^^^^^^^
の中へ:
interface ICloneable<TImpl> where TImpl : ICloneable<TImpl>
{
TImpl Clone();
}
class Sheep : ICloneable<Sheep>
{
Sheep Clone() { … }
} //^^^^^
Sheep dolly = new Sheep().Clone();
主な利点:実装型(などSheep
)は、基本型の代わりにそれ自体を参照できるようになり、型キャストの必要性が減りました(コードの最後の行で示されています)。
これは非常に便利ですが、これらの型パラメーターの制約は直感的ではなく、より複雑なシナリオでは理解するのが非常に困難になる傾向があることにも気づきました。*)
質問:同じ効果または同様の効果を実現するが、把握しやすい別のC#コードパターンを知っている人はいますか?
*)このコードパターンは、直感的でなく、理解しにくい場合があります。たとえば、次のようになります。
宣言
X<T> where T : X<T>
は再帰的であるように見え、なぜコンパイラが無限ループに陥らないのか不思議に思うかもしれません。 「もしT
が、ならX<T>
、X<T>
は本当にX<X<…<T>…>>
。」と推論します。(しかし、制約は明らかにそのように解決されません。)実装者にとっては、の代わりにどのタイプを指定する必要があるかが明確でない場合があります
TImpl
。(制約は最終的にそれを処理します。)さまざまなジェネリックインターフェイス間のタイプパラメータとサブタイピング関係をミックスに追加すると、物事はかなりすぐに管理できなくなります。