Objective C # Principle 12: Select variable initialization instead of value assignment statement
Item 12: prefer variable initializers to assignment statements
According to my personalArticleIt refers to the initialization syntax, that is, the method for directly creating instance values while declaring variables in a class.
For example, object m_o = new object (); IfCodeIt is not in any function, but in a class, it is an initialization tool, no matter whether you put it at the beginning of the class or end .)
Some classes often have more than one constructor. After a long time, it is rare to synchronize its member variables and constructors. The best way to ensure that such a thing will not happen is to initialize it directly at the declared time, instead of assigning values within each constructor. In addition, you should use the initialization tool syntax to initialize static and instance variables at the same time.
In C #, When you declare a variable, the member variable is naturally constructed. Direct assignment:
Public class myclass
{
// Declare the collection, and initialize it.
Private arraylist _ coll = new arraylist ();
}
Ignore how many constructors you will add to myclass, and _ Coll will be correctly initialized. The compiler will generate some code so that the declared instance variables will be initialized before any of your constructor calls. When you add a new constructor, _ Coll initializes it for you. When you add a new variable, you do not need to add initialization code to all constructors; you just need to initialize it directly in the declared place. Similarly, if you do not explicitly declare any constructor, the compiler will add one to you by default and add all the variable initialization processes to this constructor.
The initialization tool is more like a convenient and convenient method for constructor. The code generated during initialization is placed before the Type constructor. Initialization is executed before the constructors of the base classes of the execution type, and they are executed in the order of the declared order.
Using the initializer is the easiest way to avoid using variables without assignment in your type, but this is not very good. In the following three cases, you should not use the initialization syntax. First, if you initialize an object as 0 or null. By default, all content is initialized to 0 before any code is executed. The initialization of system 0 is based on the underlying CPU instructions, and the entire memory block is set. Any other initialization statement that sets 0 is redundant. C # The Compiler faithfully adds additional commands to set the memory to 0. There is nothing wrong with this, but the efficiency is not high. In fact, if you are processing value-type data, this is not worth it:
Myvaltype _ myval1; // initialized to 0
Myvaltype _ myval2 = new myvaltype (); // also 0
Both statements set the variable to 0. The first is to set 0 by setting the memory containing _ myval1, and the second is to use the Il command initobj, which will cause packing and unpacking for Variable _ myval2. This takes a little extra time (see Principle 17 ).
The second inefficiency occurs when you add two constructors to an object. You use the initializer to initialize variables, and all constructors initialize these variables. This version of myclass has two different arraylist objects in its constructor:
Public class myclass
{
// Declare the collection, and initialize it.
Private arraylist _ coll = new arraylist ();
Myclass ()
{
}
Myclass (INT size)
{
_ Coll = new arraylist (size );
}
}
When you create a new myclass object and specify the size of the set, you create two arrays. One of them quickly becomes a spam object. The initializer will execute before all constructors, And the constructor will create 2nd array lists. The compiler generates a version. Of course, you will never write it manually. (See Principle 14 to use an appropriate method to solve this problem)
Public class myclass
{
// Declare the collection, and initialize it.
Private arraylist _ Coll;
Myclass ()
{
_ Coll = new arraylist ();
}
Myclass (INT size)
{
_ Coll = new arraylist ();
_ Coll = new arraylist (size );
}
}
The last reason is to put initialization in the constructor to capture exceptions. You cannot use try blocks in the initialization tool. Any exceptions caused by member variables during the construction may be derived from the outside of the object. You cannot try to capture it in your class. You should move the initialization code to the constructor so that you can catch exceptions to ensure that your code is friendly (see Principle 45 ).
The variable inspector is the simplest method to ensure that the member variables are correctly initialized when the constructor is ignored. The initiator is executed before all constructors. Using this syntax means that when you add a constructor to a later version, you will not forget to add the appropriate initialization to the constructor. When the constructor generates the same member object as the initialization, it uses the initialization tool. Easy to read and maintain.
Item 12: prefer variable initializers to assignment statements
Classes often have more than one constructor. over time, it's easy for the member variables and the constructors to get out of synch. the best way to make sure this doesn't happen is to initialize variables where you declare them instead of in the body of every constructor. you shoshould utilize the initializer syntax for both static and instance variables.
Constructing member variables when you declare that variable is natural in C #. just assign a value:
Public class myclass
{
// Declare the collection, and initialize it.
Private arraylist _ coll = new arraylist ();
}
regardless of the number of constructors you eventually addto the myclass type, _ Coll will be initialized properly. the compiler generates code at the beginning of each constructor to execute all the initializers you have defined for your instance member variables. when you add a new constructor, _ Coll gets initialized. similarly, if you add a new member variable, you do not need to add initialization code to every constructor; initializing the variable where you define it is sufficient. equally important, the initializers are added to the compiler-generated default constructor. the C # compiler creates a default constructor for your types whenever you don't explain icitly define any constructors.
initializers are more than a convenient shortcut cut for statements in a constructor body. the statements generated by initializers are placed in object code before the body of your constructors. initializers execute before the base class constructor for your type executes, and they are executed in the order the variables are declared in your class.
Using initializers is the simplest way to avoid uninitialized variables in your types, but it's not perfect. in three cases, you shoshould not use the initializer syntax. the first is when you are initializing the object to 0, or null. the default system initialization sets everything to 0 for you before any of your code executes. the System-generated 0 Initialization is done at a very low level using the CPU instructions to set the entire block of memory to 0. any extra 0 Initialization on your part is superfluous. the C # compiler dutifully adds the extra instructions to set memory to 0 again. it's not wrongit's just inefficient. in fact, when value types are involved, it's very inefficient.
Myvaltype _ myval1; // initialized to 0
Myvaltype _ myval2 = new myvaltype (); // also 0
Both statements initialize the variable to all 0 s. the first does so by setting the memory containing myval1 to 0. the second uses the Il instruction initobj, which causes both a box and an Unbox operation on the _ myval2 variable. this takes quite a bit of extra time (see item 17 ).
The second inefficiency comes when you create multiple initializations for the same object. you shoshould use the initializer syntax only for variables that receive the same initialization in all constructors. this version of myclass has a path that creates two different arraylist objects as part of its construction:
Public class myclass
{
// Declare the collection, and initialize it.
Private arraylist _ coll = new arraylist ();
Myclass ()
{
}
Myclass (INT size)
{
_ Coll = new arraylist (size );
}
}
When you create a new myclass, specifying the size of the collection, you create two array lists. one is immediately garbage. the variable initializer executes before every constructor. the constructor body creates the second array list. the compiler creates this version of myclass, which you wowould never code by hand. (For the proper way to handle this situation, see item 14 .)
Public class myclass
{
// Declare the collection, and initialize it.
Private arraylist _ Coll;
Myclass ()
{
_ Coll = new arraylist ();
}
Myclass (INT size)
{
_ Coll = new arraylist ();
_ Coll = new arraylist (size );
}
}
the final reason to move initialization into the body of a constructor is to facilitate exception handling. you cannot wrap the initializers in a try block. any exceptions that might be generated during the construction of your member variables get propagated outside of your object. you cannot attempt any recovery inside your class. you shoshould move that initialization code into the body of your constructors so that you implement the proper recovery code to create your type and gracefully handle the exception (see item 45 ).
variable initializers are the simplest way to ensure that the member variables in your type are initialized regardless of which constructor is called. the initializers are executed before each constructor you make for your type. using this syntax means that you cannot forget to add the proper initialization when you add new constructors for a future release. use initializers when all constructors create the member variable the same way; it's simpler to read and easier to maintain.