Цепочка конструктора с промежуточными переменными - PullRequest
3 голосов
/ 07 декабря 2010

У меня есть следующая ситуация с перегруженными конструкторами, с которой я пытаюсь найти хорошее решение. Я не вижу, как использовать промежуточное присваивание с цепочкой конструктора.

Следующее недействительно, но показывает, что я хочу сделать

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)

, который является не только уродливым кодом, но также требует вызова базы данных дважды (если только компилятор не достаточно умен, чтобы решить это, в чем я сомневаюсь).

Есть ли лучший способ написать выше?

Ответы [ 3 ]

2 голосов
/ 07 декабря 2010

Что по этому поводу:

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
}

EDIT

На вашем месте я бы заменил конструктор фабричным методом так:

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)

1 голос
/ 07 декабря 2010

Вы можете использовать статический вспомогательный метод:

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;
}
1 голос
/ 07 декабря 2010

Да, есть.Я знаю, что пример написан на Java, но это настолько хорошее решение вашей проблемы, что некоторые усилия по переносу на C # имеют смысл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...