3

私は、適切な解決策を見つけるのに苦労している、オーバーロードされたコンストラクターに関する次の状況を抱えています。コンストラクター チェーンで中間代入を使用する方法がわかりません。

以下は有効ではありませんが、私がやりたいことを示しています

public MyThing(IServiceLocator services, int? userId)
{
    // blah....
}

public MyThing(IServiceLocator services, string userName)
{
    User user = services.UserService.GetUserByName(userName);
    int userId = user == null ? null : (int?)user.Id;
    // call the other constructor   
    this(services, userId);
}

上記を有効なコードで記述する唯一の方法は、

public MyThing(IServiceLocator services, string userName)
    : this(services,
           services.UserService.GetUserByName(userName) == null ?
              null : (int?)services.UserService.GetUserByName(userName).Id)

これは醜いコードであるだけでなく、データベース呼び出しを 2 回行う必要があります (コンパイラがそれを解決できるほど賢い場合を除きますが、私には疑問です)。

上記の書き方で何か良い方法はありませんか?

4

3 に答える 3

2

これはどうですか:

public MyThing(IServiceLocator services, string userName)
{
    User user = services.UserService.GetUserByName(userName);
    int? userId = user == null ? null : (int?)user.Id;

    Initialize(services, userId);
}


public MyThing(IServiceLocator services, int? userId)
{
    Initialize(services, userId);
}

private void Initialize(IServiceLocator services, int? userId)
{
    // initialization logic
}

編集

もし私があなたなら、コンストラクターを次のようなファクトリメソッドに置き換えます。

private MyThing(IServiceLocator services, int? userId)
{
    // blah....
} 

public static Create(IServiceLocator services, int? userId)
{
    return new MyThing(services, userId);
}

public static Create(IServiceLocator services, string userName)
{
    User user = services.UserService.GetUserByName(userName);
    int userId = user == null ? null : (int?)user.Id;

    return new MyThing(services, userId);
}

使用法:

var myThing = MyThing.Create(services, 123);
var myOtherThing = MyThing.Create(services, "userName");

コンストラクターをファクトリメソッド(refactoring.com)に置き換えます

于 2010-12-07T11:51:35.427 に答える
1

静的ヘルパーメソッドを使用できます。

public MyThing(IServiceLocator services, int? userId)
{
    // blah....
}

public MyThing(IServiceLocator services, string userName)
    : this(services, GetUserId(services, userName))
{
}

private static int? GetUserId(IServiceLocator services, string userName)
{
    User user = services.UserService.GetUserByName(userName);
    return (user == null) ? (int?)null : user.Id;
}
于 2010-12-07T12:01:06.090 に答える
1

あります、はい。がJavaであることは知っていますが、C#への移植の努力が理にかなっている問題に対する非常に優れた解決策です。

于 2010-12-07T11:47:34.597 に答える