2012-06-20 14 views
7

Ich habe eine Klasse mit zwei Konstruktoren (C#). Hier ist der Code-Schnipsel:Einen Konstruktor von einem anderen Konstruktor in derselben Klasse aufrufen

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

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

} 

Ja, ich weiß, dass ich einen Konstruktor aus einem anderen nennen kann den oben genannten Ansatz. Wenn ich jedoch in diesem Szenario Konstruktor 2 aufrufe, werden alle Anweisungen in Konstruktor 1 ausgeführt, BEVOR die Anweisung von sehr genau in Konstruktor 2 ausgeführt wird.

Was ich will, ist, dass, nachdem alle Aussagen in Konstruktor 2 laufen, dann wird es Konstruktor 1.

In meine genaue Situation nennen, ich Benutzerauthentifizierung tue. Konstruktor 1 ruft Benutzerinformationen nur mit der Benutzer-ID ab, aber Konstruktor 2 führt die Benutzerauthentifizierung mit E-Mail und Kennwort durch. Wenn ein Benutzer in der Datenbank ist, erhält er die Benutzer-ID, und jetzt möchte ich, dass Konstruktor 1 alle Eigenschaften der Klasse auffüllt.

Bitte lassen Sie mich wissen, wenn Sie zusätzliche Informationen benötigen. Wenn Sie denken, dass es einen anderen besseren Ansatz gibt, würde ich gerne den Vorschlag hören.

UPDATE 1: Ich frage mich, warum so etwas wie dieses nicht implementiert ist:

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

Interessante scenerio. Sie können die Funktionalität in eine separate Funktion verschieben oder einen überladenen Konstruktor 'FooBar (string s, int i)' erstellen. Vielleicht nicht die beste Lösung, aber nur ein paar Ideen rauswerfen. – Justin

+0

@Justin, Logik in eine andere Methode zu setzen scheint eine bessere Idee zu sein. Vielen Dank. – Farhan

Antwort

7

In diesem Fall nur verwenden Konstruktoraufrufe nicht, aber so etwas wie:

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

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

} 

Wo ich angenommen, dass Init1(..) und Init2(..) sind Verfahren im Zusammenhang mit einige spezifische Initialisierungslogik des entsprechenden Konstruktors.

Eigentlich können Sie diese Funktionsaufrufe so arrangieren, dass sie Ihren Bedürfnissen besser entsprechen.

2

Warum nicht wickeln diese Funktionalität in eine method und rufen, dass in den constuctors (oder wo immer Sie wollen)?

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 
    } 

} 

Dies ist eine generische Lösung. Sie können den Rückgabetyp entsprechend Ihrem spezifischen Szenario ändern.

2

In der Regel können Sie diese verwenden:

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

Beste Vorgehensweise - setzen Sie diese Logik nicht in den Konstruktor. Teilen Sie es mit anderen Methoden auf, die Sie nach Belieben aufrufen können, ohne sich Gedanken über die Verkettung von Konstruktoren machen zu müssen.

+0

Danke. Ich stimme zu, dass die Verkettung von Konstruktoren Verwirrung stiften kann und ich möglicherweise nicht genau das bekomme, was ich brauche. Ich werde mit anderen privaten Methoden gehen. – Farhan

8

können Sie eine andere private Methode verwenden, um die Initialisierung zu tun:

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 
    } 
} 
Verwandte Themen