2010-11-19 10 views
5

C'è un problema di progettazione come questo.Qual è il miglior design che posso usare per definire metodi con lo stesso nome?

Supponiamo di disporre di un set di classi che implementa metodi simili ma non identici.

Esempio: ClassA ha metodi come questo.

void Add(string str); 
void Delete(string str); 
List<string> GetInfo(string name); 

Un'altra classe, ClassB ha i seguenti metodi.

void Add(Dictionary Info); 
void Delete(string str); 
Dictionary GetInfo(string name); 

Quindi la natura dei metodi è simile ma i tipi di ritorno/i parametri di input sono diversi. Se sviluppo un'interfaccia per mantenere la consistenza, posso solo definire l'operazione Delete lì. In alternativa, posso pensare a un insieme di classi indipendenti senza relazioni tra loro (ovviamente nessuna implementazione di interfaccia), ma non penso che sia un buon progetto.

  1. Qual è l'approccio che posso usare per implementare questo?
  2. Sono nuovo per le interfacce generiche. Aiuta in questo caso? Se è così, ho intenzione di imparare e implementare il loro utilizzo.
+1

In che rapporto (a livello di codice e concettualmente) Se le classi A e B si distinguono? –

+0

Eseguono operazioni su oggetti simili. Nella prospettiva del punto di vista lo si può considerare come SPList e SPWeb. Entrambi rappresentano gli elementi di contenuto, ha quasi le stesse operazioni ma gli input/output possono differire. Quindi abbiamo bisogno di un buon modo per definire la "struttura", ma ancora non possiamo farlo a causa delle differenze di tipo dei parametri. –

risposta

8

È possibile utilizzare l'interfaccia generica qui. Un esempio:

interface IModifiable<T> 
{ 
    void Add(T Info); 
    void Delete(T item); 
    T GetInfo(string name); 
} 
public class MyClass : IModifiable<List<string>> 
{ 
    public void Add(List<string> list) 
    { 
     //do something 
    } 

    public void Delete(List<string> item) { } 
    public List<string> GetInfo(string name) { } 
} 
1
public interface IInt<T> { 
    void Add(T val); 
    void Delete(string str); 
    T GetInfo(string name); 
} 
3

Generics avrebbe aiutato se si può cambiare un po 'il vostro disegno:

interface IFoo<TKey, TValue> 
{ 
    void Add(TKey name, TValue value); 
    void Delete(TKey name); 
    IEnumerable<TValue> GetInfo(TKey name); 
} 

Questo non abbastanza in forma i tuoi esempi, ma quasi. Se non puoi apportare questo cambiamento, direi che le tue classi non sono abbastanza simili da avere senso per un'interfaccia comune.

Si noti inoltre che questo design è molto simile all'interfaccia IDictonary o ILookup. Forse puoi usare le interfacce esistenti invece di crearne una nuova.

0

Il problema è piuttosto vaugely definito, ma da quanto ho capito Esistono diverse possibilità prima utilizzare la definizione metodo generico

public void Detele<T>(T toDelete); //optional : where T 

e definirlo in un'interfaccia generale (o classe astratta se it'syour caso)

In caso contrario, una tecnica molto vecchia ma ancora valida è l'overloading del metodo. È possibile definire più metodi con lo stesso nome ma prendendo argomenti diversi. .Net utilizza questo modello in modo molto pesante in classi come StreamReader, ToString ecc.

Dalle firme che hai fornito sembra che tu possa trovare un uso per questo.

Terza opzione (anche se più difficile da codificare) consiste nell'utilizzare le espressioni lambda.

Add<T,P>(Action<T,P> addingAction, T source, P param) (addingAction(source,param);); 
//this is naive p.Add(q) it can be arbitralily more complicated 
aObject.Add((p,q) => p.Add(q), myObj, myParam); 

In questo modo si definisce un'azione generica di aggiunta che può quindi essere incapsulata nei propri oggetti. La firma che ho fornito può facilmente essere modificata. Inoltre, potresti non voler eseguire immediatamente l'azione, ma programmarla per l'esecuzione lenta o eseguirla in modo asincrono. Le possibilità con espressioni lambda sono infinite.

Inoltre, ho fornito un'implementazione che utilizza il delegato di Azione. È possibile convertire facilmente questo codice per utilizzare la classe Expression, tramite la quale è possibile creare i propri delegati durante l'esecuzione del codice (e memorizzarli dopo l'inizializzazione poiché si tratta di un processo piuttosto lento, cioè di riflessioni e cose.) Consiglio vivamente di abusare di delegati ed espressioni quando possibile.

Prendere cura Łukasz

Problemi correlati