Время от времени я усложняю простой интерфейс, добавляя к нему ограничение параметра самореферентного ("рефлексивного") типа. Например, я мог бы превратить это:
interface ICloneable
{
ICloneable Clone();
}
class Sheep : ICloneable
{
ICloneable Clone() { … }
} //^^^^^^^^^^
Sheep dolly = new Sheep().Clone() as Sheep;
//^^^^^^^^
в:
interface ICloneable where TImpl : ICloneable
{
TImpl Clone();
}
class Sheep : ICloneable
{
Sheep Clone() { … }
} //^^^^^
Sheep dolly = new Sheep().Clone();
Основное преимущество: реализуемый тип (например, Sheep
) теперь может ссылаться на себя, а не на базовый тип, что снижает потребность в типах. приведение (как показано в последней строке кода).
Хотя это очень хорошо, я также заметил, что эти ограничения параметров типа не интуитивно понятны и имеют тенденцию становиться действительно трудными для понимания в более сложных сценариях. *)
Вопрос: Кто-нибудь знает другой шаблон кода C #, который дает такой же эффект или что-то подобное, но более легким для понимания образом?
*) Этот код шаблон может быть неинтуитивным и трудным для понимания, например следующими способами:
Объявление
X
кажется рекурсивным, и можно задаться вопросом, почему компилятор не застревает в бесконечном цикле , рассуждение, «Если, где T: X T
являетсяX
, тоX
действительноX … >>
. " (Но очевидно, что ограничения таким образом не разрешаются.)Для разработчиков может быть неочевидно, какой тип следует указать вместо
TImpl
. (Ограничение в конечном итоге позаботится об этом.)Как только вы добавите больше параметров типа и отношений подтипов между различными универсальными интерфейсами, все довольно быстро станет неуправляемым.