8

2 つのコンストラクター (C#) を持つクラスがあります。コード スニペットは次のとおりです。

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

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

}

はい、上記のアプローチを使用して、あるコンストラクターを別のコンストラクターから呼び出すことができることを知っています。しかし、このシナリオでは、コンストラクター 2 を呼び出すと、コンストラクター 2 のステートメントが実行される前に、コンストラクター 1 のすべてのステートメントが実行されます。

私が望むのは、コンストラクター 2 のすべてのステートメントが実行された後、コンストラクター 1 を呼び出すことです。

私の正確な状況では、ユーザー認証を行っています。コンストラクター 1 はユーザー ID だけでユーザー情報を取得しますが、コンストラクター 2 は電子メールとパスワードを使用してユーザー認証を行います。ユーザーがデータベースにいる場合、ユーザー ID を取得し、コンストラクター 1 でクラスのすべてのプロパティを設定する必要があります。

追加情報が必要な場合はお知らせください。別のより良いアプローチがあると思われる場合は、提案を喜んでお聞きします。

UPDATE 1:なぜこのようなものが実装されていないのだろうか:

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

5 に答える 5

8

別のプライベートメソッドを使用して初期化を行うことができます。

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
    }
}
于 2012-06-20T15:33:53.763 に答える
8

この場合、コンストラクター呼び出しを使用しないでください。次のようなものです。

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

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

}

とはInit1(..)Init2(..)対応するコンストラクターの特定の初期化ロジックに関連するメソッドです。

実際には、この関数呼び出しをニーズに合わせて調整できます。

于 2012-06-20T15:31:38.610 に答える
2

その機能をいくつかにラップしてmethod、それをコンストラクター(または必要な場所)で呼び出してみませんか?

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
    }

}

これは一般的なソリューションです。特定のシナリオに応じて、返品タイプを変更できます。

于 2012-06-20T15:30:38.130 に答える
2

一般的に、これを使用できます。

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");
    }    
}
于 2012-06-20T15:30:44.500 に答える
1

最善の方法 - そのロジックをコンストラクターに入れないでください。コンストラクターの連鎖を気にせずに自由に呼び出すことができる他のメソッドに分割します。

于 2012-06-20T15:31:40.910 に答える