6

which declaration/instantiation is better and WHY ?

public class MainWindow
{
   private Test _test;

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

OR

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

   public MainWindow()
   {

   }
}
Elisabeth
  • 20,496
  • 52
  • 200
  • 321
  • 1
    Duplicate of a duplicate of a .... See http://stackoverflow.com/questions/298183/c-member-variable-initialization-best-practice – Tony Nov 18 '10 at 21:31

9 Answers9

3

Ask yourself this question: what happens when you add other constructors to MainWindow? Do you want to then have to remember to invoke other constructors to ensure that _test is correctly initialized? Or is it okay for _test to not be initialized if another constructor is used?

Personally when creating a UI component I would move as many points of failure out of the constructor as possible, and I would move something like that to either the Loaded event handler, or keep it as you did in option 2 (which keeps the initialization nicely localized in the file).

slugster
  • 49,403
  • 14
  • 95
  • 145
2

I'd go for a third option:

public class MainWindow
{
   private Test _test;

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

By injecting the dependency you make your code easier to unit test.

Jackson Pope
  • 14,520
  • 6
  • 56
  • 80
  • The OP had `_test` as as a member variable of the class, which means it shouldn't be testable separately from the `MainWindow`, instead the test should be aimed at `MainWindow`. IOW: IoC is inappropriate for `_test`. – slugster Nov 18 '10 at 21:33
  • This way allows you to mock it out in testing. – Jackson Pope Nov 18 '10 at 21:34
  • @slugster: It depends on what Test does. It SHOULD be injected if it provides any kind of data to MainWindow. You get predefined (testable) result if you can provide that data from your test (through a stub/mocked object) – jgauffin Nov 18 '10 at 21:37
  • I am aware of mocking and testing and IoC. **Read the context of the code**: if it is okay to declare it as `private Test _test = new Test();` then it was never intended to be injected. – slugster Nov 18 '10 at 21:39
  • @slugster you are right I never had the intention to do any Unit Tests with this class Test, maybe the name have been badly choosen... I want to do stuff with the _test object WITHIN the constructor that I forgot to say! – Elisabeth Nov 18 '10 at 22:49
2

It's better to do it inside the constructor to make it plain what's happening when the object is created, especially when you go to write subclasses.

Generally though it's a matter of taste and the most important thing is to be consistent in your choice.

izb
  • 50,101
  • 39
  • 117
  • 168
1

This is the same as the difference between

int i;
...
i = 0;

and

int i = 0;

My opinion is that the initialization should be close to the declaration if possible, in ideal case a part of it. Beside the bonus in readability you get smaller chances to forget the initialization. So the 2nd variant is a better one.

Vlad
  • 35,022
  • 6
  • 77
  • 199
1

I don't think you can say that one declaration is better then the other, it's all about the logic of your form, if you don't want to initiate Test on the form start-up, but on a button click then the first declaration is better.

Stefan P.
  • 9,489
  • 6
  • 29
  • 43
  • That's right, if "new Test()" involves heavy memory usage it is wiser to call only if needed, like a button event or when ever it's imperative to create a type Test class. – Stefan P. Nov 18 '10 at 21:40
0

The latter, because declaration and initialization occur on the same line... easier to read, harder to make a mistake.

spender
  • 117,338
  • 33
  • 229
  • 351
0

The second is cleanest imho. I usually only create objects in the constructor when they need to be initialized with parameters.

No parameters

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

   public MainWindow()
   {

   }
}

with parameters:

public class MainWindow
{
   private Test _test;

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

As Jackson Pope said, it can be a good idea to add a constructor for the object to make it easier to start using DI's later on. You can read about DI/IoC here: http://www.codeproject.com/KB/architecture/DependencyInjection.aspx

jgauffin
  • 99,844
  • 45
  • 235
  • 372
0

In the example that you gave, neither of the to choices is better. Both of these snippets instantiate a member variable during construction of the class. The only real difference is that, in the second case, the member is initialized before the constructor is executed.

The only time that it really makes a difference is when the member variable needs information passed into its constructor that the Main class gets in it's constructor. Then you have no choice but to use the second option.

For example:

public class MainWindow  
{  
   private Test _test;  

   public MainWindow(int i)  
   {  
       _test = new Test(i);  
   }  
} 
CAP
  • 79
  • 2
  • 5
0

It doesn't make a difference at all, because the compiler generates exactly the same IL. In terms of readability it is just a matter of personal taste. I prefer the latter version but with the readonly modifier:

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

   public MainWindow()
   {

   }
}

This is especially easier to read and to maintain when the class has more than one constructor.

bitbonk
  • 48,890
  • 37
  • 186
  • 278
  • In the given example it's true, but when `MainWindow` would be derived from some other class, there is a difference: in the second case `Test` will be constructed _before_ the base constructor. – Vlad Nov 18 '10 at 21:46