Restrições de parâmetro do tipo reflexivo: X <T> em que T: X <T> - alguma alternativa mais simple
Muitas vezes, estou tornando uma interface simples mais complicada adicionando uma restrição de parâmetro do tipo auto-referência ("reflexiva"). Por exemplo, eu posso transformar isso:
interface ICloneable
{
ICloneable Clone();
}
class Sheep : ICloneable
{
ICloneable Clone() { … }
} //^^^^^^^^^^
Sheep dolly = new Sheep().Clone() as Sheep;
//^^^^^^^^
para dentro
interface ICloneable<TImpl> where TImpl : ICloneable<TImpl>
{
TImpl Clone();
}
class Sheep : ICloneable<Sheep>
{
Sheep Clone() { … }
} //^^^^^
Sheep dolly = new Sheep().Clone();
Vantagem principal: um tipo de implementação (comoSheep
) agora pode se referir a si mesmo em vez de seu tipo base, reduzindo a necessidade de conversão de tipo (conforme demonstrado pela última linha de código
Embora isso seja muito bom, também notei que essas restrições de parâmetros de tipo não são intuitivas e tendem a se tornar realmente difíceis de compreender em cenários mais complexo *)
Questãolguém conhece outro padrão de código C # que obtém o mesmo efeito ou algo semelhante, mas de uma maneira mais fácil de entende
*) Esse padrão de código pode não ser intuitivo e difícil de entender, por exemplo. das seguintes maneiras:
<, ul>A declaraçãoX<T> where T : X<T>
parece ser recursivo e pode-se perguntar por que o compilador não fica preso em um loop infinito, raciocínio,"E seT
é umX<T>
, entãoX<T>
é realmente umX<X<…<T>…>>
. " (Mas as restrições obviamente não são resolvidas dessa maneira.)
Para implementadores, pode não ser óbvio que tipo deve ser especificado no lugar deTImpl
. (A restrição acabará por resolver isso.)
Depois de adicionar mais parâmetros de tipo e relacionamentos de subtipagem entre várias interfaces genéricas à mistura, as coisas ficam incontroláveis rapidament