我刚才发现(我想再次确认)如果你声明了一个类级变量,那么在调用类构造函数或load之前不应该调用它的构造函数。原因是性能 - 但还有其他原因可以做到这一点吗?这条规则有例外吗?
即:这是我根据我认为的最佳做法做的事情:
public class SomeClass
{
private PersonObject _person;
public SomeClass()
{
_person = new PersonObject("Smitface");
}
}
反对:
public class SomeClass
{
private PersonObject _person = new PersonObject("Smitface");
public SomeClass()
{
}
}
答案 0 :(得分:12)
如果将变量设置在构造函数之外,则不存在可用的错误处理(handeling)。虽然在您的示例中它没有任何区别,但在许多情况下您可能希望进行某种错误处理。在这种情况下,使用您的第一个选项是正确的。
如果有一些构造函数失败,Nescio谈到了这会对你的应用程序产生什么影响。
因此,我总是使用选项#1。
答案 1 :(得分:6)
老实说,如果你看一下IL,那么在第二种情况下发生的一切就是编译器将初始化移动到你的构造函数。
就个人而言,我喜欢在构造函数中看到所有初始化。如果我正在进行一次性原型项目,我不介意在同一地点进行初始化和声明,但对于我的“我想保留这个”项目,我在构造函数中完成所有这些。
答案 2 :(得分:4)
实际上,尽管其他人已经说过,但无论你的初始化是在构造函数内部还是在构造函数之外,都可以重要,因为如果对象在层次结构中,则在对象构造期间存在不同的行为(即事物运行的顺序是不同的。)
请参阅Eric Lippert的this post和this post,它更详细地解释了两者之间的语义差异。
所以答案是,在大多数情况下,它没有任何区别,并且它在性能方面肯定没有任何差别,但在少数情况下它可以有所作为,你应该知道为什么,并根据这个做出决定。
答案 3 :(得分:2)
有一种称为依赖注入或控制反转(IOC)的常见模式,它提供了这两种机制,用于将依赖对象(如DAL类)“注入”到一个可以延长依赖关系链的类中(从数据库开始) )
在这种模式中,使用ctor,你会
公共类SomeClass
{
私人PersonObject per;
public SomeClass(PersonObject person)
{
per = person;
}
}
private PersonObject Joe = new PersonObject(“Smitface”);
SomeClass MyObj = new SomeClass(Joe);
现在,您可以传入一个真正的DAL类进行生产调用 或单元测试方法中的测试DAL类......
答案 4 :(得分:1)
这取决于如何使用变量的上下文。自然常量和static或readonly应该在声明时初始化,否则它们通常应该在构造函数中初始化。这样,您可以更换设计模式,了解对象的实例化,而不必担心变量何时初始化。
答案 5 :(得分:1)
您通常应该更喜欢第二个变体。它对代码中的更改更加健壮。假设您添加了一个构造函数。现在你必须记住在那里初始化你的变量,除非你使用第二个变体。
当然,只有在没有令人信服的理由使用构造函数初始化时(如discorax所述),这才算正确。
答案 6 :(得分:0)
我更喜欢后者,但仅仅因为我觉得它更整洁。
这是个人偏好,他们都做同样的事情。
答案 7 :(得分:0)
第一个声明实际上更清洁。第二个隐藏了构造函数在静态构造函数中初始化类的事实。如果由于任何原因构造函数失败,则整个类型对于应用程序的其余部分都是不可用的。
答案 8 :(得分:0)
我喜欢在构造函数中初始化,因为这样一切都发生在一个地方,并且因为如果您决定稍后创建一个重载的构造函数,它会更容易。
此外,它还有助于提醒我在解构器中要清理的内容。
答案 9 :(得分:0)
后者可以利用惰性实例化,即在引用变量之前不会初始化变量
答案 10 :(得分:0)
我认为这类问题只是风格问题,所以谁关心你这样做的方式。语言允许两者,所以其他人都会这两种方式。不要做出错误的假设。
答案 11 :(得分:-3)
我更喜欢尽快初始化变量,因为它避免了(某些)空错误。
编辑:显然在这个简化的例子中没有区别,但是在一般情况下我认为,如果可能的话,在声明类变量时将它们初始化是一种好习惯。这使得在初始化之前无法引用变量,从而消除了在构造函数中初始化字段时可能出现的一些错误。
当你获得更多类变量并且构造函数中的初始化序列变得更复杂时,更容易引入错误,其中一个初始化依赖于尚未发生的另一个初始化。