2010-03-04 14 views
6

Vedo molti metodi che specificano un'interfaccia come valore di ritorno. Il mio pensiero è vero che significa: il mio metodo può restituire ogni tipo di classe che eredita da quell'interfaccia? se no, per favore dammi una buona rispostaSe un metodo restituisce un'interfaccia, che cosa significa?

+7

@ddimitrov le domande più elementari sono consentite su SO, potrebbe esserci stata un'altra risposta plausibile, che è forse il motivo per cui ha chiesto. il tuo commento non aggiunge nulla. –

+0

@ sam-holder, sono corretto. Cancellato il mio commento originale – ddimitrov

risposta

11

Sì, il metodo può restituire qualsiasi tipo che implementa tale interfaccia.

Ecco un esempio:

using System; 

class Foo 
{ 
    public IComparable GetComparable() 
    { 
     // Either of these return statements 
     // would be valid since both System.Int32 
     return 4; 
     // and System.String 
     return "4"; 
     // implement System.IComparable 
    } 
} 
+2

Aggiungo che è quasi sempre una cattiva idea cercare di annusare il tipo effettivo e il downcast. –

+2

@Steven - Di solito è una cattiva idea sì, ma ci sono casi in cui downcasting può essere molto utile. –

+2

Bel esempio :) –

4

Sì, questo metodo potrebbe restituire un oggetto di qualsiasi tipo che implementa tale interfaccia.

Ma, per utilizzare i membri non di interfaccia di un tipo particolare, è necessario eseguire il cast per tale tipo.

+0

Sì, ho provato a sistemarlo subito, ma anche qualcun altro stava modificando il mio post. Mi sono incasinato tutto. Ma ho ricevuto il mio distintivo di pulizia. :) –

+0

Il metodo può restituire un tipo di classe o un valore di tipo boxed. Non può restituire un tipo di valore reale. La distinzione può a volte essere importante, dal momento che i tipi di valore in box si comportano come tipi di classi.In alcuni casi, una routine che accetta un 'U dove U: IEnumerable ' può comportarsi in modo molto diverso quando viene passato un 'IEnumerable ' quando ha passato una struct come 'List .Enumerator'. – supercat

5

Sì, significa che l'unica cosa che sai sull'oggetto restituito è che implementa l'interfaccia.

In effetti, il tipo effettivo dell'oggetto potrebbe non essere nemmeno accessibile al codice chiamante. Potrebbe essere un tipo privato in un assembly separato.

E infatti, il metodo può restituire un tipo diverso da una chiamata alla successiva (come nel caso di una fabbrica astratta).

+0

Una risposta in competizione, ma mi sento in dovere di revocare la votazione! I tuoi bit di informazioni extra sarebbero molto utili a qualcuno che cerchi di capirlo. –

+0

@Patrick Karcher - Grazie! :-) –

3

C++ supporta una tecnica di programmazione denominata polimorfismo. Questa è una classe derivata che può apparire come una classe base per un altro codice che non conosce nulla delle classi derivate. Date un'occhiata al suo esempio:

class Shape 
{ 
public: 
    virtual float Area() const = 0; 
}; 

class Rectangle: public Shape 
{ 
public: 
    Rectangle (float width, float height) 
     : m_width(width) 
     , m_height(height) 
    {} 

    virtual float Area() const 
    { 
     return m_width * m_height; 
    } 

private: 
    float m_width; 
    float m_height; 
}; 

class Circle: public Shape 
{ 
public: 
    Circle (float radius) 
     : m_radius(radius) 
    {} 

    virtual float Area() const 
    { 
     return 3.141592653f*(m_radius*m_radius); 
    } 

private: 
    float m_radius; 
}; 

ora si può vedere da questo codice abbiamo creato una forma di classe di base (la nostra interfaccia) e due classi derivate che si specializzano questa classe, un rettangolo, un altro un cerchio. Ora creiamo una funzione che stampa l'area di una forma:

void PrintArea (const Shape& shape) 
{ 
    printf("Area of shape = %f",shape.Area()); 
} 

Questa funzione non si preoccupa se un cerchio di rettangolo. O ci importa è che ha superato una forma e che puoi ottenere l'area di esso, indipendentemente dal tipo.

Quindi questo codice utilizza questa funzione:

Rectangle r (5.0f,4.0f); 
Circle c (25.0f); 

PrintArea(r);  // Print the area of the rectangle 
PrintArea(c);  // Print the area of the circle 

Spero che questo aiuti.

+1

Oops Chiedo scusa Ho scritto questo in C++, non ho letto abbastanza bene la domanda per vedere che intendevi C#. Ma vale lo stesso processo. Fammi sapere se vuoi che io riscrivi il codice di esempio sopra in C#. – Cthutu

+0

grazie Cthutu. No questo campione è molto chiaro. –