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)

这不仅是丑陋的代码,而且还需要两次数据库调用(除非编译器足够聪明,我对此表示怀疑)。

有没有更好的方法来编写上述内容?

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

有,是的。我知道该示例是用 Java 编写的,但它是解决您的问题的一个很好的解决方案,因此移植到 C# 的一些努力确实有意义。

于 2010-12-07T11:47:34.597 回答
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 回答