2011-12-19 9 views
15

Sto cercando di implementare (C#) un metodo di interfaccia in una classe, restituendo un tipo derivato invece che il tipo base, quale definito nell'interfaccia:interfaccia Override tipo di metodo di ritorno con classe derivata nell'attuazione

interface IFactory 
{ 
    BaseCar GetCar(); 
} 

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

dove, naturalmente:

class MyCar : BaseCar 
{ 

} 

Tuttavia, il seguente errore accade:

'myfactory' non implementa il membro di interfaccia 'IFactory.GetCar()'. 'MyFactory.BaseCar()' non può implementare IFactory.GetCar() 'perché non ha il tipo di ritorno corrispondente di' BaseCar '.

Qualcuno può indicarmi perché questo non funziona, e come sarebbe il modo migliore per aggirare il problema?

+0

Questo è un duplicato: [ “Interfaccia non implementato” quando Tornando tipo derivato] (http://stackoverflow.com/questions/1121283/ interfaccia-non-implementato-quando-ritorno-tipo-derivato) e [polimorfismo per le proprietà specificate dalle interfacce] (http://stackoverflow.com/questions/3670069/polymorphism-for-properties-specified-by-interfaces) –

+0

@ Austin ho rimosso il mio commento scusa .. – MethodMan

+0

Grazie @cod y-grey, in qualche modo ha perso quei link in precedenza. – iDPWF1

risposta

16

Usa Generics

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

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


class MyCar : BaseCar 
{ 

} 
+0

'GetCar' in' MyFactory' deve essere pubblico e 'T' è covariante, quindi è possibile contrassegnarlo con' out' sull'interfaccia se si utilizza C# 4.0. – vcsjones

+0

@vcsjones: Se BaseFactory implementa l'IFactory e DerivedFactory ereditano BaseFactory ma implementa l'IFactory , esiste una garanzia, quando si utilizza la covarianza, che l'utilizzo di DerivedFactory come IFactory utilizzerà l'implementazione DerivedFactory di GetCar? – supercat

4

Il metodo GetCar deve restituire un BaseCar per implementare l'interfaccia. Come dice l'errore, il tipo restituito dal metodo della classe deve corrispondere al tipo di ritorno del metodo dell'interfaccia.

Non c'è nulla che possa impedire che si crea un'istanza di MyCar, per poi tornare che:

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

Un'alternativa, se si desidera ottenere la versione digitato della nuova classe, è quello di utilizzare farmaci generici come da John's answer.

+1

Hai davvero bisogno di trasmettere? –

+0

Buon punto, corretto. –

+0

In questo caso, c'è, perché GetCar() viene utilizzato da molti altri in diversi scenari, in cui devono restituire MyCar, MyOtherCar, ecc., Senza che debbano eseguire il cast da BaseCar ogni volta. – iDPWF1

7

Ci sono 2 modi per ottenere questo risultato. Puoi utilizzare i generici o implementare esplicitamente i membri dell'interfaccia.

Generics

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

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

esplicitamente implementate membri

interface IFactory 
{ 
    BaseCar GetCar(); 
} 

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

    MyCar GetCar() 
    { 
    } 
} 
Problemi correlati