2012-03-30 12 views
5

Ho una classe personalizzata che uso per creare stringhe di tabella. Vorrei riscrivere il codice in modo da poter concatenare gli operatori. Qualcosa di simile:Come si dichiara una classe in C# in modo da poter concatenare i metodi?

myObject 
    .addTableCellwithCheckbox("chkIsStudent", isUnchecked, isWithoutLabel) 
    .addTableCellwithTextbox("tbStudentName", isEditable) etc. 

Così sembra che avrei ciascuno di questi metodi (funzioni) restituire l'oggetto stesso in modo che possa quindi chiamare un altro metodo (funzione) sull'oggetto risultante, ma non riesco a capire come ottenere la classe # per riferirsi a se stessa.

Qualsiasi aiuto?

risposta

6

Così si creerebbe un'interfaccia fluida come questa:

class FluentTable 
{ 
    //as a dumb example I'm using a list 
    //use whatever structure you need to store your items 
    List<string> myTables = new List<string>(); 

    public FluentTable addTableCellwithCheckbox(string chk, bool isUnchecked, 
                 bool isWithoutLabel) 
    { 
    this.myTables.Add(chk); 
    //store other properties somewhere 
    return this; 
    } 

    public FluentTable addTableCellwithTextbox(string name, bool isEditable) 
    { 
    this.myTables.Add(name); 
    //store other properties somewhere 
    return this; 
    } 
    public static FluentTable New() 
    { 
    return new FluentTable(); 
    } 
} 

Ora si potrebbe usare in questo modo:

FluentTable tbl = FluentTable 
        .New() 
        .addTableCellwithCheckbox("chkIsStudent", true, false) 
        .addTableCellwithTextbox("tbStudentName", false); 

Questo dovrebbe darvi un'idea di base di come avete bisogno di andare su esso. Vedi fluent interfaces on wikipedia.

Un modo più corretto per farlo sarebbe quello di implementare un'interfaccia fluida:

interface IFluentTable 
{ 
IFluentTable addTableCellwithCheckbox(string chk, bool isUnchecked, 
                 bool isWithoutLabel) 
IFluentTable addTableCellwithTextbox(string name, bool isEditable) 
//maybe you could add the static factory method New() here also 
} 

E poi implementarlo: class FluentTable : IFluentTable {}

+0

tutte le risposte erano buone, ma questo va davvero oltre, grazie questo è stato davvero utile –

7

Usa la parola chiave this come valore di ritorno, in questo modo si torna e si può catena per sempre:

ClassName foo() 
{ 
    return this; 
} 
+0

hey thx landr thx –

0

assicurarsi che ogni metodo restituisce un'interfaccia che dichiara i metodi che si desidera chiamare sul tuo catena .

EX pubblico IADD Aggiungi()

In questo modo se IADD definito un metodo Add è possibile chiamare Aggiungi dopo aver Aggiungere, dopo Aggiungi. Ovviamente puoi anche aggiungere i metodi di otterh alla stessa interfaccia. In genere viene chiamata un'API fluente

+0

Con questo approccio è possibile utilizzare diverse classi per implementare le varie funzioni – TGH

3

Questo dovrebbe farti chiudere.

public class SomeObject 
{ 
    public SomeObject AddTableCellWithCheckbox(string cellName, bool isChecked) 
    { 
     // Do your add. 

     return this; 
    } 
} 

Buona fortuna, Tom

7

Questa notazione è chiamata Fluent.

Per esempio, la forma più semplice sarebbe

public class MyObject { 
    public MyObject addTableCellwithCheckbox(...) { 
     ... 
     return this; 
    } 
    public MyObject addTableCellwithTextbox(...) { 
     ... 
     return this; 
    } 
} 

Nella forma più bella, si dichiara interfacce (ad esempio, IMyObject) con questi metodi, e hanno la classe MyObject implementare tale interfaccia. Il tipo restituito deve essere l'interfaccia, come illustrato nell'esempio di Wikipedia sopra.

Se il codice sorgente della classe non è accessibile, è anche possibile implementare una classe di estensione in modo simile.

+2

+1 per * fluente *. –

Problemi correlati