在构造函数或类顶部创建一个对象

6
哪种声明/实例化更好,为什么?
public class MainWindow
{
   private Test _test;

   public MainWindow()
   {
       _test = new Test();
   }
}

或者

public class MainWindow
{
   private Test _test = new Test();

   public MainWindow()
   {

   }
}

1
重复的副本,再次重复的副本...... 请参见https://dev59.com/FXVC5IYBdhLWcg3wbghT - Tony
9个回答

3
问问自己这个问题:当你给MainWindow添加其他构造函数时会发生什么?你是否想要记得调用其他构造函数以确保_test正确初始化?或者如果使用另一个构造函数,_test不被初始化是否可以?
个人而言,在创建UI组件时,我会尽可能将失败点从构造函数中移出,并将类似的东西移动到Loaded事件处理程序中,或者像选项2一样保持它(在文件中使初始化非常局部化)。

2

最好在构造函数内部完成此操作,以便在创建对象时清晰地了解所发生的情况,尤其是在编写子类时。

总的来说,这是一种品味问题,最重要的是在您的选择中保持一致性


2

我会选择第三个选项:

public class MainWindow
{
   private Test _test;

   public MainWindow(Test test)
   {
       _test = test;
   }
}

通过注入依赖项,您可以使代码更易于单元测试。

OP在类的成员变量中有_test,这意味着它不能与MainWindow分开进行测试,而应该将测试针对于MainWindow。换句话说:IoC不适用于_test - slugster
这种方式允许你在测试中进行模拟。 - Jackson Pope
@slugster:这取决于Test的作用。如果它向MainWindow提供任何类型的数据,那么它应该被注入。如果您可以通过存根/模拟对象从测试中提供该数据,则可以获得预定义的(可测试的)结果。 - jgauffin
我了解模拟、测试和控制反转(IoC)。阅读代码的上下文:如果将其声明为private Test _test = new Test();是可以的,那么它从未打算被注入。 - slugster
@slugster 你说得对,我从来没有打算使用这个名为Test的类进行任何单元测试,也许命名不当... 我想在构造函数中使用_test对象做一些事情,这是我忘记说的! - Elisabeth

1

我认为你不能说一个声明比另一个更好,这完全取决于你的表单逻辑,如果你不想在表单启动时初始化测试,而是在按钮点击时进行,则第一种声明更好。


没错,如果“new Test()”涉及到大量的内存使用,最好只在需要时调用它,比如按钮事件或者在必须创建一个Test类的情况下。 - Stefan P.

1

这就好比两者之间的区别

int i;
...
i = 0;

并且

int i = 0;

我的观点是,如果可能的话,初始化应该尽可能靠近声明,理想情况下是其中的一部分。除了提高可读性的奖励外,您还可以减少忘记初始化的机会。因此,第二种变体更好。


0
后者,因为声明和初始化发生在同一行...更容易阅读,更难出错。

0

在我看来,第二种方法最为简洁。通常情况下,我只会在构造函数中创建需要使用参数进行初始化的对象。

无需参数

public class MainWindow
{
   private Test _test = new Test();

   public MainWindow()
   {

   }
}

带参数:

public class MainWindow
{
   private Test _test;

   public MainWindow()
   {
       _test = new Test("abc")
   }
}

如Jackson Pope所说,为对象添加构造函数可以使以后更容易地使用DI。您可以在此处了解有关DI / IoC的详细信息:http://www.codeproject.com/KB/architecture/DependencyInjection.aspx

0
在你提供的例子中,两种选择都没有更好的。这些片段都在类的构造期间实例化成员变量。唯一真正的区别是,在第二种情况下,成员变量在执行构造函数之前初始化。
唯一真正有区别的时候是当成员变量需要传递信息到它的构造函数中,而主类在它的构造函数中获取该信息。那么你别无选择,只能使用第二个选项。
例如:
public class MainWindow  
{  
   private Test _test;  

   public MainWindow(int i)  
   {  
       _test = new Test(i);  
   }  
} 

0

这其实没有任何区别,因为编译器生成的 IL 代码是完全相同的。在可读性方面,这只是个人口味的问题。我更喜欢带有 readonly 修饰符的后一种版本:

public class MainWindow
{
   private readonly Test _test = new Test();

   public MainWindow()
   {

   }
}

当类有多个构造函数时,这样做尤其易于阅读和维护。


在给定的示例中是正确的,但当MainWindow从其他类派生时,就会有所不同:在第二种情况下,Test将在基础构造函数之前被构造。 - Vlad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接