2013-04-17 2 views
5

Diciamo che ho un'interfaccia che molte molte classi distinte implementano:Soluzione per essere in grado di mettere il codice in interfacce

public interface IHaveObjects 
{ 
    object firstObject(); 
} 

(Nota: non riesco a farne una classe di base astratta come implementatori di IHaveObjects maggio già una classe base)

Ora voglio aggiungere un nuovo metodo all'interfaccia, in modo che un implementatore dell'interfaccia possa avere un comportamento speciale per esso. Idealmente vorrei fare qualcosa di simile:

public interface IHaveObjects 
{ 
    object firstObject(); 
    object firstObjectOrFallback() 
    { 
     return firstObject(); 
    } 
} 

poi andare a quella implementazioni dell'interfaccia e dargli l'override:

public class ObjectHaverPlus : IHaveObjects 
{ 
    public override object IHaveObjects.firstObjectOrFallback() 
    { 
     return firstObject() ?? getDefault(); 
    } 
} 

Tuttavia è vietato in C# per fornire un corpo di un metodo in un interfaccia, e vorrei evitare che ogni singolo implementatore di IHaveObjects cada in una definizione di firstObjectOrFallback(). (Immagina se ce ne sono centinaia o migliaia)

C'è un modo per farlo senza un sacco di copia incolla?

+1

Perché non creare una seconda interfaccia per quel caso speciale? Non è possibile avere ereditarietà multipla delle classi, ma è possibile implementare più interfacce. – Tim

risposta

2

Che ne dici di introdurre una seconda interfaccia che eredita da IHaveObjects.

Quindi è sufficiente modificare queste classi, che richiedono la nuova interfaccia con il nuovo metodo.

Questo appare come:

interface I1 
    { 
     void Method1(); 
    } 

    interface I2 : I1 
    { 
     void Method2(); 
    } 
+0

Oh ... mi piace ... non ho nemmeno pensato all'ereditarietà nella mia risposta. Silly me :) – Tim

+0

Sì, ma questo non è possibile in C#. Gli ho dato un modo alternativo. – Tomtom

+0

@Tomtom Penso che questo sia quello che voglio fare. Significa fare un altro controllo per vedere se l'oggetto è dell'interfaccia estesa, ma dovrebbe andare bene.Grazie – Patashu

1

forse ho capito male la tua domanda, ma perché non usare una seconda interfaccia, qualcosa di simile:

public interface IHaveObjectsEnhanced 
{ 

    object FirstObjectOrFallback(); 
} 

allora si potrebbe implementare la prima e la seconda interfaccia:

public class ObjectHaverPlus : IHaveObjects, IHaveObjectsEnhanced 
{ 

    public object FirstObject() 
    { 

    } 

    public object FirstObjectOrFallback() 
    { 
     return FirstObject() ?? GetDefault(); 
    } 

} 
2

Questo è il problema con le interfacce - non hanno alcuna implementazione di default quindi le modifiche apportate a loro stanno interrompendo le modifiche: il codice deve essere modificato per funzionare con la nuova versione dell'interfaccia.

Poiché le implementazioni dispongono già di classi base da sole - non è possibile trasformarle in classi astratte, né lo è C# con ereditarietà di più classi.

Quello che puoi fare è pensare - è davvero un metodo di interfaccia? Oppure potrebbe essere implementato come interfaccia extension method (non l'ho provato, ma suppongo che funzionerà bene)?

Se si tratta di un metodo su interfaccia e dovrebbe rimanere lì - si potrebbe pensare di rompere questa interfaccia in due parti, seconda ereditando dal primo (IHaveObjectsAndSupportDefault : IHaveObjects) e utilizzare questa interfaccia dove il valore predefinito è veramente necessario (come altri le risposte indicano).