2011-12-19 7 views
15

Estoy tratando de poner en práctica (C#) un método de interfaz en una clase, volviendo un tipo derivado en lugar del tipo de base como se define en la interfaz:interfaz de Anulación tipo de retorno método con clase derivada de la aplicación

interface IFactory 
{ 
    BaseCar GetCar(); 
} 

class MyFactory : IFactory 
{ 
    MyCar GetCar() 
    { 
    } 
} 

Cuando, por supuesto:

class MyCar : BaseCar 
{ 

} 

sin embargo, el error siguiente ocurre:

'MyFactory' no implementa miembro de interfaz 'IFactory.GetCar()'. 'MyFactory.BaseCar()' no puede implementar IFactory.GetCar() 'porque no tiene el tipo de retorno coincidente de' BaseCar '.

¿Alguien puede indicarme por qué esto falla y cuál sería la mejor manera de evitarlo?

+0

Este es un duplicado: [ “La interfaz no implementa” cuando Volviendo tipo derivado] (http://stackoverflow.com/questions/1121283/ interface-not-inserted-when-returning-derived-type) y [polimorfismo para las propiedades especificadas por las interfaces] (http://stackoverflow.com/questions/3670069/polymorphism-for-properties-specified-by-interfaces) –

+0

@Austin quité mi comentario lo siento .. – MethodMan

+0

Gracias @cod y-gray, de alguna manera se perdió esos enlaces previamente. – iDPWF1

Respuesta

16

Uso Genéricos

interface IFactory<T> where T: BaseCar 
{ 
    T GetCar(); 
} 

class MyFactory : IFactory<MyCar> 
{ 
    MyCar GetCar() 
    { 
    } 
} 


class MyCar : BaseCar 
{ 

} 
+0

'GetCar' en' MyFactory' debe ser público, y 'T' es covariante, por lo que puede marcarlo así con' out' en la interfaz si usa C# 4.0. – vcsjones

+0

@vcsjones: Si BaseFactory implementa IFactory y DerivedFactory hereda BaseFactory pero implementa IFactory , ¿hay alguna garantía, al usar covarianza, que usar una DerivedFactory como IFactory usará la implementación DerivedFactory de GetCar? – supercat

4

Su método GetCar tiene que devolver BaseCar para implementar la interfaz. Como dice el error, el tipo de devolución del método de la clase debe coincidir con el tipo de devolución del método de la interfaz.

No hay nada que le para la creación de una instancia de MyCar, a continuación, volver que:

BaseCar GetCar() 
{ 
    return new MyCar(); 
} 

Una alternativa, si desea obtener la versión mecanografiada de la nueva clase, es el uso de los genéricos como por John's answer.

+1

¿De verdad tienes que lanzar? –

+0

Buen punto, corregido. –

+0

En este caso, hay, porque GetCar() es utilizado por muchos otros en diferentes escenarios, donde tienen que devolver MyCar, MyOtherCar, etc., sin tener que lanzarlo desde BaseCar todo el tiempo. – iDPWF1

7

Hay 2 maneras de lograr esto. Puede usar genéricos o implementar miembros de interfaz explícitamente.

Genéricos

interface IFactory<T> where T: BaseCar 
{ 
    T GetCar(); 
} 

class MyFactory : IFactory<MyCar> 
{ 
    MyCar GetCar() 
    { 
    } 
} 

implementados explícitamente a los miembros

interface IFactory 
{ 
    BaseCar GetCar(); 
} 

class MyFactory : IFactory 
{ 
    BaseCar IFactory.GetCar() 
    { 
     return GetCar(); 
    } 

    MyCar GetCar() 
    { 
    } 
} 
Cuestiones relacionadas