2012-05-29 20 views
24

Si una interfaz especifica una propiedad o método para devolver otra interfaz, ¿por qué no se permite que las implementaciones de la primera interfaz "cambien" el tipo de devolución a un tipo más específico?¿Por qué una implementación de interfaz no puede devolver un tipo más específico?

Tomemos un ejemplo para ilustrar:

interface IFoo 
{ 
    IBar GetBar(); 
} 
interface IBar 
{ } 

class Foo : IFoo 
{ 
    // This is illegal, we are not implementing IFoo properly 
    public Bar GetBar() 
    { 
     return new Bar(); 
    } 
} 

class Bar : IBar 
{ } 

sé cómo hacer que funcione, eso es no mi preocupación.

puedo simplemente ya sea:

  • Cambiar el tipo de retorno de GetFoo()-IBar o
  • explícitamente implementar la interfaz y simplemente llamar GetBar del IFoo.GetBar() método

lo que realmente estoy preguntando es el razonamiento para no solo permitir que compile el código anterior. ¿Hay algún caso en el que lo anterior no cumpla con el contrato especificado por IFoo?

+1

Hay una tercera forma, que es ligeramente más conveniente que las dos anteriores. Puede implementar la interfaz con una clase abstracta. Y luego, en tu clase "concreta", heredas la clase abstracta en lugar de la interfaz. Luego, en su clase "concreta", puede ocultar los métodos básicos con la palabra clave "nueva". Está funcionando decentemente para mí. – BrainSlugs83

+0

Siento que el comentario de BrainSlugs83 aquí es una respuesta, ya que proporciona una solución decente. –

Respuesta

17

Normalmente, diría que sería un caso de equilibrar el beneficio con la complejidad añadida de admitir dicha función. (Todas las características requieren esfuerzo para diseñar, documentar, implementar, probar, y luego los desarrolladores también deben ser educados acerca de ellas.) Tenga en cuenta que podría haber algunas complejidades significativas si desea admitir la devolución de un tipo de valor que implemente una interfaz, por ejemplo (ya que eso termina en una representación diferente, en lugar de solo una referencia).

En este caso, no creo que el CLR incluso es compatible con esta característica, lo que haría muy difícil que C# lo hiciera limpiamente.

Acepto que sería una característica útil, pero sospecho que no se ha considerado lo suficientemente útil como para justificar el trabajo adicional requerido.

+7

Jon tengo una pregunta? ¿Cómo escribes tanto en 1 minuto? –

+0

+1 porque el punto en "... complejidad añadida de ..." pero no estoy seguro de que pueda ser útil. Después de todo, una interfaz es un contrato, si necesita un método como ese, puede implementar el método de interfaz de manera explícita y agregar otro método con el tipo _required_ return, así que ... ¿para qué sirve eso? –

+1

@Adriano: puedes, sí. Pero es molesto que tengas que hacerlo, y la implementación de interfaz explícita tiene sus propios inconvenientes y complejidades. Evito la implementación de interfaces explícitas donde puedo, y si se admiten tipos de retorno covariantes, sería otro lugar donde podría evitarlo :) –

3

La función que pregunta se llama "covarianza de tipo de retorno". Como se indica en on Wikipedia, tanto Java como C++ lo tienen, lo que quizás hace que sea sorprendente que C# no lo haga.

Eric Lippert confirma en los comentarios sobre esta respuesta que esta característica no se implementó porque no se consideró que valía la pena el esfuerzo de implementación. (Una revisión previa de esta respuesta le asignó a Eric la responsabilidad de esa decisión, dice que esto es incorrecto y que si alguna persona es responsable, fue Anders Hejlsberg.)

De todos modos, ahora hay varias propuestas para agregar al idioma (ver https://github.com/dotnet/roslyn/issues/357, https://github.com/dotnet/csharplang/blob/master/proposals/covariant-returns.md, https://github.com/kingces95/coreclr/issues/2), así que tal vez se implementará en los próximos años. Según esas discusiones, no parece que existan razones profundas por las cuales la función no debería existir en C# en principio, sino que nunca se ha juzgado que valga la pena implementarla.

+3

La característica se agregó a Java un par de años antes de formar parte del equipo de diseño de C#, por lo que mi opinión no se consideró en ese momento. Y mientras estaba en el equipo de diseño de C#, para mi recuerdo, el equipo de diseño nunca tuvo en cuenta la cuestión. Por lo tanto, sería más exacto decir que * Anders * no pensó que valiera la pena el esfuerzo. No creo que sea una mala característica, y la usaría si C# la tuviera. Estoy de acuerdo en que hay muchas más características que me gustaría tener una mayor prioridad. –

Cuestiones relacionadas