Let decir que tengo una clase como esta:Liskov SUSTITUCIÓN y Composición
public sealed class Foo
{
public void Bar
{
// Do Bar Stuff
}
}
Y quiero extenderlo a añadir algo más allá de lo que un método de extensión podría hacer .... Mi única opción es la composición:
public class SuperFoo
{
private Foo _internalFoo;
public SuperFoo()
{
_internalFoo = new Foo();
}
public void Bar()
{
_internalFoo.Bar();
}
public void Baz()
{
// Do Baz Stuff
}
}
Aunque esto funciona, es un montón de trabajo ... sin embargo todavía me encuentro con un problema:
public void AcceptsAFoo(Foo a)
que puede pasar en un Foo aquí, pero no es un súper Foo, porque C# no tiene idea de que SuperFoo realmente califica en el sentido de Sustitución de Liskov ... Esto significa que mi clase extendida a través de la composición tiene un uso muy limitado.
Por lo tanto, la única manera de solucionarlo es de esperar que los diseñadores API originales dejaron una interfaz por ahí:
public interface IFoo
{
public Bar();
}
public sealed class Foo : IFoo
{
// etc
}
Ahora, puedo aplicar IFoo en SuperFoo (que desde SuperFoo ya implementa Foo, es solo una cuestión de cambiar la firma).
public class SuperFoo : IFoo
Y en el mundo perfecto, los métodos que consumen Foo consumiría IFoo de:
public void AcceptsAFoo(IFoo a)
Ahora, C# entiende la relación entre SuperFoo y Foo debido a la interfaz común y todo está bien.
El gran problema es que .NET sella muchas clases que de vez en cuando sería bueno ampliar, y generalmente no implementan una interfaz común, por lo que los métodos API que toman un Foo no aceptarían un SuperFoo y usted puede agregar una sobrecarga
Entonces, para todos los fanáticos de la composición ... ¿Cómo se supera esta limitación?
Lo único que se me ocurre es exponer públicamente el Foo interno, para que pueda pasarlo de vez en cuando, pero parece desordenado.
Esta es la mejor respuesta, aunque SixLetterVariable presenta un excelente punto. – FlySwat
+1 después de leer más la pregunta, en realidad la has respondido. ¡No me di cuenta de que estaba buscando una solución técnica al principio! – user7116