构造函数链接中间变量

时间:2010-12-07 11:40:41

标签: c# design-patterns constructor constructor-chaining

我有以下的重载构造函数,我正在努力寻找一个很好的解决方案。我看不到如何使用构造函数链接的中间赋值。

以下内容无效,但显示了我想要做的事情

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 个答案:

答案 0 :(得分: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");

Replace Constructor with Factory Method (refactoring.com)

答案 1 :(得分:1)

有,是的。我知道example是Java中的,但是对于你的问题来说这是一个很好的解决方案,因为移植到C#的一些努力确实有意义。

答案 2 :(得分: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;
}