"Effective C #" reading notes (ii)-. NET Resource Hosting
Brief introduction
Continued "Effective C #" reading notes (a)-C # language habits.
In. NET, the GC helps us manage memory, and we don't need to worry about memory leaks, resource allocations, and pointer initialization issues. However, it is also not omnipotent, because unmanaged resources require our own cleanup, such as file handles, database connections, GDI + objects, COM objects, and so on.
Directory
- 12. It is recommended to use member initializers instead of assignment statements
- 13. Initialize static member variables correctly
- 14. Minimize repetitive initialization logic
- Use using and try/finally to clean up resources
- 16. Avoid creating non-essential objects
- 17, the implementation of standard destruction mode
- 18. Area score Type and reference type
- 19, guaranteed 0 is the valid state of the value type
- 20, the constant and atomicity of the guaranteed value type
12. It is recommended to use member initializers instead of assignment statements
1. Member initializer: Initializes the variable when it is declared, rather than in each constructor.
2. You should avoid using member initializers in the following 3 scenarios:
(1) When you want to initialize the object to be 0 or null. Because the system's default initialization work (before all code execution) sets everything to 0 or null, we're doing an extra step. And, if it is a value type, then performance is very poor.
// initialized to 0 New // also 0
Each of these two statements initializes the variable to 0, but the first one is implemented by setting the memory containing MyVal1 to 0, and the second using the initobj IL directive, which results in a one-time unboxing operation on the MYVAL2 variable, which consumes additional performance and timing.
(2) You need to perform different initialization methods for the same variable:
classProgram {/// <summary> ///declaring and initializing/// </summary> Privatelist<string> _lables =Newlist<string>(); PublicProgram () {} PublicProgram (intcapacity) {_lables=Newlist<string>(capacity); } }
When initializing the class, if you are using a constructor with capacity, then the List<string> object represents 2 initialization, and the first one becomes a garbage object.
(3) The appropriate reason to place the initialization code on the constructor: you can conveniently manage Try-catch.
13. Initialize static member variables correctly
1. All static member variables of the type should be initialized before the instance of the type is used. A static constructor is a special function that will be executed before all other methods, variables, or properties are accessed for the first time. You can use this function to initialize static variables and to implement a singleton pattern, for example.
2. Static initializers and static constructors are the best choice for initializing static members of a class.
3. The most common reason to use static constructors instead of static initializers is that you can catch and handle exceptions.
14. Minimize repetitive initialization logic
1. If multiple constructors contain similar logic, we should extract them into a common constructor, which avoids code duplication, and can generate more efficient code with the constructor initializer.
classMyClass {Privatelist<string>_lables; Private string_name; PublicMyClass (): This(0,string. Empty) {} PublicMyClass (intCapacity =0,stringName ="") {_lables=Newlist<string>(capacity); _name=name; } }
The second constructor uses "" To give the default value of name instead of string. Empty because of string. Empty is not a compile-time constant, but a static property defined in the string class, so it cannot be used as the default value for a parameter.
2. Sequence of operations to create the first instance of a type:
(1) The static variable is set to 0;
(2) Execution of static variable initializers;
(3) Executing the static constructor of the base class;
(4) Execute the static constructor function;
(5) The instance variable is set to 0;
(6) Executing the instance variable initializer;
(7) Executing the appropriate instance constructors in the base class;
(8) Executes the instance constructor.
3. Use initializers to initialize simple resources, use constructors to initialize members that require complex logic, and colleagues don't forget to extract the call into a constructor to reduce duplication.
4. Only one initializer can be used in a constructor definition, either using this () delegate to another constructor or using base () to invoke the constructor of the base class.
Use using and try/finally to clean up resources
1. Types that use unmanaged system resources must be released using Dispose () of the IDisposable interface, and a using () statement will generate a try/finally block.
16. Avoid creating non-essential objects
1.GC can manage memory well, but allocating and destroying objects on the heap will always take a long time, no matter how efficient, and if too many reference objects are created, it can have a serious effect on the performance of the program.
Public void Paint () { using (varnew Font ("Arial"10.0f ) { Console.WriteLine ($" painting with {MyFont} ");} }
If the method is called very frequently. Another Font object is created each time it is called, but it contains exactly the same content as before. Every time the GC cleans up the rubbish for you, it's obviously very inefficient.
The MyFont can be promoted to a static variable.
Private readonly Static New Font ("Arial"10.0f); Public void Paint () { Console.WriteLine ($" use {_myfont} for painting "); }
2. Reduce the number of objects created in the program.
(1) Promote the common local variables to member variables;
(2) Provides a class that holds a singleton object for a common instance of a type.
3. Complex string manipulation with StringBuilder
17, the implementation of standard destruction mode
The implementation of the 1.idisposable.dispose () method needs to complete the following 4 tasks:
(1) Release of all unmanaged resources;
(2) Release all managed resources, including the release event listener;
(3) Set a status flag indicating that the object has been destroyed;
(4) Skip the end operation and invoke the GC. SuppressFinalize (This).
18. Area score Type and reference type
1. In general, most of the references we create are reference types.
2. Determine the criteria for creating a value type of 4
(1) The primary responsibility of this type is data storage;
(2) is the public interface of this type defined by accessing its data member properties?
(3) Are you sure that the type will never have a derived type?
(4) Are you sure that the type will never need polymorphic support?
3. Use a value type to represent the type of underlying storage data, and use reference types to encapsulate the behavior of the program.
4. If you are unsure about the future use of the type, you should select the reference type.
19, guaranteed 0 is the valid state of the value type
The default initialization process for 1..NET systems sets all objects to 0, and 0 is recommended as the default value for enumeration types.
2. The enumeration (enum) must set 0 as a valid selection for the enumeration value. All enumeration values are derived from System.ValueType. The default value of the enumeration starts at 0.
3. When creating a custom enumeration value, make sure that 0 is a valid option. If you define flag, you can define 0 as no flag is selected.
enum Week { 0, 1, 2, 3, 4 , 5 , 6 , 7 }
20, the constant and atomicity of the guaranteed value type
1. Constant: The value remains unchanged since it was created. Because the internal state cannot be changed, many unnecessary error checks can be omitted, it is thread-safe, and can be safely exposed to the outside world because the caller cannot change the internal state of the object.
2. When designing a constant type, make sure that there are no vulnerabilities that cause the internal state to be changed externally. Because value types cannot be derived, you do not have to worry about being affected by derived classes.
However, if the constant is a mutable reference type field, we should make a defensive copy of these mutable types.
class MyClass { privatereadonlyobject[] _objs; Public MyClass (icollection<object> objs) { newobject[ Objs. Count]; 0 ); Copy } public ienumerable<Object> objs = _objs; }
static void Main (string [] args) { var o BJS = new object [ 10 var myClass = new MyClass (OBJS); objs[ " hi ; Console.WriteLine (MyClass.Objs.ToArray () [ 1
Because an array is a reference type, if you copy a copy without using CopyTo, the external objs changes directly affect _OBJS in MyClass because they point to the same reference.
2. Do not blindly add {get; set;} to each attribute.
"Bo Master" anti-bone Aberdeen
"Original" http://www.cnblogs.com/liqingwen/p/6761409.html
[. NET] Effective C # reading notes (ii)-. NET Resource Hosting