2013-07-29 9 views
12

Ho una semplice domanda C# (quindi credo). Sono un principiante con la lingua e mi sono imbattuto in un problema riguardante le interfacce e le classi che li implementano. Il problema èMetodo di classe che non è nell'interfaccia

ho l'interfaccia iA

interface iA 
{ 
    bool method1 
    bool method2 
    bool method3 
} 

e 3 classi che implementano l'interfaccia: classe B, C e D

class B : iA 
{ 
    public bool method1 
    public bool method2 
    public bool method3 
} 

se la classe B aveva un altro metodo che non è in l'interfaccia, diciamo method4() e ho il seguente:

iA element = new B(); 

e quindi vorrei usare:

element.method4(); 

avrei ricevuto un errore che dice che io non ho un method4() che prende un primo argomento di tipo iA.

La domanda è: Posso avere un oggetto di tipo interfaccia e istanziato con una classe e chiedere a quell'oggetto di chiamare un metodo dalla classe, un metodo che non è nell'interfaccia?

Una soluzione che ho avuto è stata quella di utilizzare una classe astratta tra l'interfaccia e le classi derivate, ma IMO che avrebbe messo l'interfaccia fuori dal campo di applicazione. Nel mio design vorrei utilizzare solo l'interfaccia e le classi derivate.

+1

'if (elemento è typeof (B)) ((B) element) .method4();' questo dovrebbe aiutare – wudzik

+5

Un nuovo utente che chiede una domanda chiara e ben formattata. Questo è raro, congratulazioni e benvenuto. :) – Otiel

+0

Buona domanda. +1 Se offri lo scenario reale, possiamo consigliarti sul miglior approccio al design. –

risposta

2

È necessario eseguire il cast del tipo di interfaccia per il tipo di classe; di solito lo facciamo tramite come:

B b = element as B; // <- try cast element as B 

    if (!Object.RefernceEquals(null, b)) { // <- element is B or can be legaly interpreted as B 
    b.method4(); 
    } 

Il vantaggio del "come" è che c'è una sola operazione cast, mentre "è" e (B) hanno a che fare due calchi.

4

Sì, è possibile. Hai solo bisogno di lanciare il tipo di interfaccia per il tipo di classe come questo:

iA element = new B(); 
((B)element).method4(); 

Come suggerito da wudzik, si dovrebbe verificare se elemnt è del tipo corretto:

if(element is B) 
{ 
    ((B)element).method4(); 
} 
+2

Nota a margine: è possibile aggiungere "if (element is typeof (B))" per assicurarsi che l'elemento sia 'B' – wudzik

+0

Probabilmente non si vuole farlo? –

+0

Questo è un buon punto. Lo aggiungerò alla mia risposta. –

2

Senza di colata che si possa fare Questo.

interface iA 
{ 
    bool method1(); 
    bool method2(); 
    bool method3(); 
} 

interface IFoo : iA 
{ 
    bool method4(); 
} 

class B : IFoo 
{ 
    public bool method1() {} 
    public bool method2() {} 
    public bool method3() {} 
    public bool method4() {} 
} 

IFoo element = new B();  
element.method4(); 

NB: Prova ad utilizzare il capitale I prefisso per C# interfacce.

+0

In questo modo si evita il controllo ortografico e il cast, ma ora si ha un oggetto diverso, IFoo. Se l'utente ha un oggetto iA, sarà comunque necessario verificare se quell'oggetto è un IFoo (e lanciato), per poter eseguire method4. –

+1

Sì, ma dal punto di vista del design è più intelligente lavorare contro interfacce come questa, piuttosto che contro tipi concreti. È una soluzione che si adatta meglio poiché ora è più semplice estendere quali tipi implementano le varie interfacce. –

Problemi correlati