2012-06-20 15 views
7

Ho una classe con due costruttori (C#). Ecco il frammento di codice:Chiamare un costruttore da un altro costruttore nella stessa classe

public class FooBar() 
{ 
    public FooBar(string s) 
    { 
     // constructor 1, some functionality 
    } 

    public FooBar(int i) : this("My String") 
    { 
     // constructor 2, some other functionality 
    } 

} 

Sì, lo so che posso chiamare un costruttore da un altro utilizzando l'approccio di cui sopra. Ma in questo scenario, se chiamo il costruttore 2, tutte le istruzioni nel costruttore 1 verranno eseguite PRIMA la stessa istruzione nel costruttore 2 viene eseguita.

Quello che voglio è che dopo tutte le dichiarazioni di costruttore 2 vengono eseguiti, allora chiamerà il costruttore 1.

Nella mia situazione esatta, sto facendo l'autenticazione dell'utente. Il costruttore 1 recupera le informazioni utente con solo l'ID utente, ma il costruttore 2 esegue l'autenticazione utente tramite e-mail e password. Se un utente si trova nel database, ottiene l'ID utente e ora desidero che il costruttore 1 inserisca tutte le proprietà della classe.

Per favore fatemi sapere se avete bisogno di ulteriori informazioni. Se pensi che ci sia un altro approccio migliore, sarei felice di ascoltare il suggerimento.

UPDATE 1: Mi chiedo perché una cosa del genere non è implementata:

public FooBar(bool b) 
{ 
    // constructor 3, some more functionality 
    this.FooBar("My String"); // calling constructor 1 
} 
+2

scenerio Interessante. È possibile spostare la funzionalità in una funzione separata o creare un costruttore sovraccaricato 'FooBar (string s, int i)'. Potrebbe non essere la soluzione migliore, ma solo buttare fuori alcune idee. – Justin

+0

@Justin, mettere la logica in un altro metodo sembra essere un'idea migliore. Grazie. – Farhan

risposta

7

In questo caso basta non utilizzare le chiamate costruttore, ma qualcosa di simile:

public class FooBar() 
{ 
    public FooBar(string s) 
    { 
     Init1(); 
    } 

    public FooBar(int i) 
    { 
     Init2(); 
     Init1(); 
    } 

} 

Dove dovrei che Init1(..) e Init2(..) sono metodi legati alla qualche logica di intializzazione specifica del costruttore corrispondente.

In realtà è possibile organizzare questa funzione in modo che risponda meglio alle proprie esigenze.

2

Perché non avvolgere tale funzionalità in qualche method e chiamare che nelle constuctors (o dove vuoi)?

public class FooBar() 
{ 
    public FooBar(string s) 
    { 
     LoadUser(s); 
    } 

    public FooBar(int i) : this("My String") 
    { 
     var s=CheckUser(); 
     LoadUser(s); 
    } 

    private string CheckUser() 
    { 
     return "the id/name from db"; 
    } 
    private void LoadUser(string s) 
    { 
      //load the user 
    } 

} 

Questa è una soluzione generica. È possibile modificare il tipo di reso in base al proprio scenario specifico.

2

In generale è possibile utilizzare questo:

public class FooBar() 
{ 
    private Test(string s) 
    { 
     // Some functionality 
    } 

    public FooBar(string s) 
    { 
     Test(s); 
    } 

    public FooBar(int i) 
    { 
     // Do what you need here 
     Test("MyString"); 
    }  
} 
1

Miglior approccio: non mettere questa logica nel costruttore. Scoprilo con altri metodi che puoi chiamare a piacimento senza preoccuparti del concatenamento del costruttore.

+0

Grazie. Sono d'accordo sul fatto che il concatenamento del costruttore può causare confusione e non posso ottenere esattamente ciò di cui avevo bisogno. Vado usando altri metodi privati. – Farhan

8

È possibile utilizzare un altro metodo privato di fare l'inizializzazione:

public class FooBar() 
{ 
    public FooBar(string s) 
    { 
     this.Initialize(s); 
    } 

    public FooBar(int i) 
    { 
     this.Initialize("My String"); 
    } 

    private void Initialize(string s) { 
     // Do what constructor 1 did 
    } 
} 
Problemi correlati