2010-12-07 3 views
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) 

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

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

+0

Если болит, не делайте этого :-) – VVS 2010-12-07 12:11:09

ответ

1

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

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 
} 

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"); 

Replace Constructor with Factory Method (refactoring.com)

+0

Это работает очень хорошо для моего примера. Если вы начнете добавлять больше конструкторов, хотя в итоге вы получите много дублированного кода (т. Е. Если вы на самом деле хотите цепочки из более чем двух конструкторов). – fearofawhackplanet 2010-12-07 12:00:33

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; 
} 
Смежные вопросы