2012-06-20 21 views
7

Mam klasy z dwoma konstruktorami (C#). Oto fragment kodu:Wywołanie konstruktora z innego konstruktora w tej samej klasie

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

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

} 

Tak, wiem, że mogę wywołać jednego konstruktora z innego przy użyciu wyżej wymienionego podejścia. Ale w tym scenariuszu, jeśli wywołasz konstruktora 2, wszystkie instrukcje w konstruktorze 1 będą działały PRZED wykonaniem samego polecenia w konstruktorze 2.

Co chcę jest, że po wszystkie dane przedstawione w konstruktorze 2 są prowadzone, to będzie wywołanie konstruktora 1.

W moim dokładnym sytuacji, robię uwierzytelnienia użytkownika. Konstruktor 1 pobiera informacje o użytkowniku za pomocą samego identyfikatora użytkownika, ale konstruktor 2 dokonuje uwierzytelnienia użytkownika za pomocą adresu e-mail i hasła. Jeśli użytkownik jest w bazie danych, otrzymuje identyfikator użytkownika, a teraz chcę, aby konstruktor 1 wypełniał wszystkie właściwości klasy.

Proszę dać mi znać, jeśli potrzebujesz dodatkowych informacji. Jeśli uważasz, że istnieje inne lepsze podejście, chętnie wysłucham sugestii.

UPDATE 1: Zastanawiam się, dlaczego coś takiego nie jest realizowany:

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

Ciekawe scenerio. Możesz przenieść funkcjonalność w oddzielnej funkcji lub zrobić przeciążony Konstruktor 'FooBar (string s, int i)'. Może nie być najlepszym rozwiązaniem, ale po prostu wyrzucać kilka pomysłów. – Justin

+0

@Justin, wprowadzenie logiki w innej metodzie wydaje się być lepszym pomysłem. Dzięki. – Farhan

Odpowiedz

7

W tym przypadku po prostu nie korzystać z połączeń konstruktora, ale coś takiego:

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

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

} 

Gdzie mam to Init1(..) i Init2(..) są metody związane z pewna specyficzna logika intializacji odpowiedniego konstruktora.

Właściwie możesz ustawić tę funkcję w sposób, który lepiej odpowiada Twoim potrzebom.

2

Dlaczego nie zawijać tę funkcjonalność do jakiegoś method i nazwać, że w constuctors (lub gdziekolwiek chcesz)?

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 
    } 

} 

To jest ogólne rozwiązanie. Możesz zmienić typ zwrotu zgodnie ze swoim konkretnym scenariuszem.

2

W ogóle można użyć tego:

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

Najlepsze podejście - nie umieszczaj tej logiki w konstruktorze. Podziel go na inne metody, które możesz dowolnie wywoływać, nie martwiąc się o łańcuchy konstruktorów.

+0

Dzięki. Zgadzam się, że łańcuchy konstruktorów mogą powodować zamieszanie i może nie uzyskać dokładnie tego, czego potrzebowałem. Używam innych prywatnych metod. – Farhan

8

Można zastosować inną metodę prywatną zrobić inicjalizacji:

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 
    } 
} 
Powiązane problemy