C# 嵌套构造函数(或工厂方法)是否良好,或者每个人都应该完成所有初始化工作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/284896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is nesting constructors (or factory methods) good, or should each do all init work
提问by Andrew Backer
Is it a good idea (from a design POV) to nest constructor calls for overloaded New or Factory style methods? This is mostly for simple constructors, where each overload builds on the previous one.
嵌套构造函数调用重载的 New 或 Factory 样式方法是否是一个好主意(从设计 POV)?这主要用于简单的构造函数,其中每个重载都建立在前一个重载之上。
MyClass( arg1 ) {
_arg1 = arg1;
_otherField = true;
_color="Blue"
}
MyClass( arg1, arg2) : this(arg1) {
_arg2 = arg2
}
MyClass( arg1, arg2, arg3) : this(arg1, ar2) {
_arg3 = arg3;
}
Or with factory methods:
或者使用工厂方法:
static NewInstance(arg1 ) {
_arg1 = arg1;
}
static NewInstance(arg1, arg2) {
f = NewInstance(arg1);
f._arg2 = arg2;
}
//... and so on
I can see a few drawbacks on both sides
我可以看到双方的一些缺点
- Nesting hides what the constructor is doing
- Not nesting duplicates all the functionality
- 嵌套隐藏了构造函数正在做什么
- 不嵌套重复所有功能
So, is doing this a good idea, or does it set me up for something I'm just not seeing as a problem. For some reason I feel uneasy doing it, mostly because it divides up the responsibility for initializing.
那么,这样做是一个好主意,还是让我为一些我不认为有问题的事情做好了准备。出于某种原因,我觉得这样做很不自在,主要是因为它划分了初始化的责任。
Edit: @Jon Skeet: I see now why this was bothering me so much. I was doing it backwards! I wrote the whole thing and didn't even notice, it just smelled. Most other cases I have (that I wrote), do it the way you recommend, but this certainly isn't the only one that I have done like this. I do notice that the more complicated ones I did properly, but the simple ones I seem to have gone sloppy. I love micro edits. I also like acronymns!
编辑: @Jon Skeet:我现在明白为什么这让我如此困扰。我是倒着做的!我写了整件事,甚至没有注意到,它只是闻起来。我拥有的大多数其他案例(我写的)都按照您推荐的方式进行,但这肯定不是我这样做的唯一案例。我确实注意到我做得正确的更复杂的,但我似乎已经变得草率了。 我喜欢微编辑。我也喜欢缩写!
采纳答案by Jon Skeet
I think it's reasonable to chain constructors together, but I do it the other way - the version with fewer parameters calls the version with more parameters. That way it makes it very clear what's happening, and all the real "logic" (beyond the default values) is in a single place. For example:
我认为将构造函数链接在一起是合理的,但我以另一种方式这样做 - 参数较少的版本调用参数较多的版本。这样它就可以非常清楚发生了什么,并且所有真正的“逻辑”(超出默认值)都在一个地方。例如:
public Foo(int x, int y)
{
this.x = x;
this.y = y;
precomputedValue = x * y;
}
private static int DefaultY
{
get { return DateTime.Now.Minute; }
}
public Foo(int x) : this(x, DefaultY)
{
}
public Foo() : this(1, DefaultY)
{
}
Note that if you have lots of constructor overloads, you may wish to move to static factory methods instead - that usually makes the code clearer, as well as allowing multiple methods to take the same set of parameters, e.g.
请注意,如果您有很多构造函数重载,您可能希望改为使用静态工厂方法 - 这通常会使代码更清晰,并允许多个方法采用相同的参数集,例如
public static XmlDocument FromText(string xml)
public static XmlDocument FromFile(string filename)
回答by Chris Marisic
2016 Edit: Still ahead of the time, C# is radically cutting back or eliminating its records support and default constructor support for C# 7, maybe C# 8 finally.
2016 年编辑:仍然领先于时间,C# 正在从根本上减少或消除其对 C# 7 的记录支持和默认构造函数支持,最终可能是 C# 8 。
2015 Edit: I was far ahead of the time. C#6 and C#7 are removing the need for constructors.
2015 编辑:我远远领先于时间。C#6 和 C#7 不再需要构造函数。
If you're developing in .Net 3.5 I recommend never using constructors. The only exception I leave for this is if you are using an injection constructor for dependency injection. With .Net 3.5 they created object initializers which allow you to do
如果您在 .Net 3.5 中进行开发,我建议您永远不要使用构造函数。我为此留下的唯一例外是,如果您使用注入构造函数进行依赖注入。使用 .Net 3.5,他们创建了对象初始值设定项,允许您执行
var myclass = New MyClass { arg1 = "lala", arg2 ="foo" }
This will initalize the class with values assigned for arg1 and arg2 while leaving arg3 as
这将使用为 arg1 和 arg2 分配的值初始化类,同时将 arg3 保留为
default(typeof(arg3)).