异常抛弃构造函数&初始化。最佳实践

时间:2010-07-12 20:29:04

标签: c# constructor initialization

我有DataProvider类(DAL),需要“year”作为参数。它使用如下:

using (var provider = new DataProvider(year))
{
   provider.SomeRepostitory.DoSomethingUsefull(); 
}

DataProvider构造函数代码处理配置 - 因此它可以抛出异常。并且不建议使用异常throwable构造函数。所以我添加了Init方法并将所有可抛出的代码放在那里:

var provider = new DataProvider();
provider.Init(year);

但是现在有两行代码而不是一行代码,并且在代码中多次创建了提供程序,我将这两行放到了结构静态方法中:

using (var provider = DataProvider.Create(year))
{
  ...
}

没问题还是有更好的解决方案?

提前谢谢!

4 个答案:

答案 0 :(得分:3)

  

DataProvider构造函数代码处理   配置 - 所以它可以抛出   例外。和异常抛出   不建议使用构造函数。

为什么他们“不推荐”?查看Microsoft基类库,您将看到足够接近每个构造函数检查传递给它的参数,如果参数无效,则抛出某种类型的参数异常。为什么你会让某人在没有告诉他们的情况下实例化一个无效状态的对象?早早失败,努力失败。

抛出异常的构造函数是一个更好的API编程,而不是必须使用单独的初始化方法(我个人讨厌两阶段初始化;很容易忘记第二次调用)。除非有令人信服的理由要避免它,否则我只会在构造函数中进行检查。

如果你真的想使用静态工厂方法(除非你需要松散耦合,否则没有任何问题),请确保默认构造函数是私有的,因此用户必须使用适当的工厂方法。

答案 1 :(得分:2)

我认为有一个工厂方法对对象进行一些初始化是完全合理的。如果您不应该在没有初始化的情况下使用该对象,请将构造函数设置为private(或protected),以便只有类中的静态方法才能调用构造函数。

答案 2 :(得分:0)

如果要将调用链接在一起,可以让Init方法返回this。像:

var provider = new DataProvider().Init(year);

但是如果你来调用.Init(),那么工厂方法样式可能会更有帮助。

答案 3 :(得分:0)

你可以逃避懒惰的实例化吗?在创建它的年份通过,但在使用之前不要实际初始化它。这会将异常移到第一个调用而不是构造,但它似乎符合您的要求。