C# 异常抛出构造函数&;初始化。最佳做法

C# 异常抛出构造函数&;初始化。最佳做法,c#,constructor,initialization,C#,Constructor,Initialization,我有一个需要“年”作为参数的数据提供程序类(DAL)。它是这样使用的: using (var provider = new DataProvider(year)) { provider.SomeRepostitory.DoSomethingUsefull(); } DataProvider构造函数代码处理配置-因此它可以抛出异常。不建议使用可抛出异常的构造函数。所以我添加了Init方法并将所有可丢弃的代码放在那里: var provider = new DataProvider();

我有一个需要“年”作为参数的数据提供程序类(DAL)。它是这样使用的:

using (var provider = new DataProvider(year))
{
   provider.SomeRepostitory.DoSomethingUsefull(); 
}
DataProvider构造函数代码处理配置-因此它可以抛出异常。不建议使用可抛出异常的构造函数。所以我添加了Init方法并将所有可丢弃的代码放在那里:

var provider = new DataProvider();
provider.Init(year);
但现在有两行代码,而不是一行,并且由于提供者在代码中多次创建,我将这两行代码放入fabric静态方法中:

using (var provider = DataProvider.Create(year))
{
  ...
}
这样可以吗?还是有更好的解决方案


提前谢谢你

我认为使用工厂方法对对象进行初始化是完全合理的。如果不需要初始化就不能使用对象,请将构造函数设为私有(或受保护),这样只有类中的静态方法才能调用构造函数。

我认为使用factory方法对对象进行初始化是完全合理的。如果不需要初始化就不能使用对象,请将构造函数设为私有(或受保护),以便只有类中的静态方法才能调用构造函数。

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

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

但是,如果必须调用
.Init()
,则工厂方法样式可能更有用。

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

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

但是,如果您必须调用
.Init()
,那么工厂方法样式可能会更有用。

您可以不使用延迟实例化吗?在您创建它的年份中传递,但在使用它之前不要实际初始化它。这会将异常移到第一个调用而不是构造,但它似乎满足了您的要求。

您能通过延迟实例化解决问题吗?在您创建它的年份中传递,但在使用它之前不要实际初始化它。这会将异常移到第一个调用而不是构造,但它似乎满足您的要求

数据提供者构造函数代码处理 配置-因此它可以抛出 例外情况。和异常丢弃 不建议使用构造函数

为什么“不推荐”?查看Microsoft基类库,您会发现几乎每个构造函数都会检查传递给它的参数,如果参数无效,就会抛出某种类型的参数异常。为什么你不告诉别人就让别人实例化一个无效状态的对象?早早失败,努力失败

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

如果您真的想使用静态工厂方法(除非您需要使其松散耦合,否则没有错),请确保默认构造函数是私有的,以便用户被迫使用适当的工厂方法

数据提供者构造函数代码处理 配置-因此它可以抛出 例外情况。和异常丢弃 不建议使用构造函数

为什么“不推荐”?查看Microsoft基类库,您会发现几乎每个构造函数都会检查传递给它的参数,如果参数无效,就会抛出某种类型的参数异常。为什么你不告诉别人就让别人实例化一个无效状态的对象?早早失败,努力失败

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


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

这意味着您必须在每次使用“worker”方法时捕获潜在的异常,这可能是相当大的开销。这还意味着对该方法的第一次调用不像其他调用那样可预测,这与良好的API设计背道而驰,这意味着每次使用“worker”方法时都必须捕获潜在的异常,这可能会带来相当大的开销。这也意味着对该方法的第一次调用不像其他调用那样可预测,这与良好的API设计背道而驰,