Effective C# 50 Specific Ways to Improve Your C# Item 12 ~ 13 Neo2012/07/25 1
Agenda.NET Resource Management.NET Resource Management Item 12: Prefer Variable Initializers to Assignment Statements Item 12: Prefer Variable Initializers to Assignment Statements Item 13: Initialize Static Class Members with Static Constructors Item 13: Initialize Static Class Members with Static Constructors
.NET Resource Management The Garbage Collector (GC) controls managed memory for you. The Garbage Collector (GC) controls managed memory for you. – Runs in its own thread to remove unused memory from your program. – Make contiguous block of memory.
.NET Resource Management Don’t use Destructor like the C++ Don’t use Destructor like the C++ – In the previous example, the code eventually exits the critical section, but, in C#, it doesn't exit the critical section when the function exits. – Relying on finalizers also introduces performance penalties. // Good C++, bad C#: class CriticalSection { public: // Constructor acquires the system resource. CriticalSection( ) { EnterCriticalSection( ); } // Destructor releases system resource. ~CriticalSection( ) { ExitCriticalSection( ); } }; // usage: void Func( ) { // The lifetime of s controls access to // the system resource. CriticalSection s; // Do work. //... // compiler generates call to destructor. // code exits critical section. }
.NET Resource Management Memory leaks and a host of other pointer-related problems are no longer your problem Memory leaks and a host of other pointer-related problems are no longer your problem – Use finalizers to ensure proper cleanup of those non- memory resources.
Prefer Variable Initializers to Assignment Statements Item 12:
What is the different between them? Initializers Initializers – Assign value at definition time – Avoid mistakes Assignment Statements Assignment Statements – Assign(Decide) value in constructor – Facilitate exception handling
Why we use Initializers? Initializers can help to avoid human error Initializers can help to avoid human error – Case: Multiple constructors
Exceptional Cases Case 1: Don’t use Initializers on value type Case 1: Don’t use Initializers on value type – Initializers set memory to 0 – Initobj also set memory to 0 – It’s like do nothing….class public auto ansi beforefieldinit MyClass extends [mscorlib]System.Object {.method public hidebysig specialname rtspecialname instance void.ctor() cil managed {.maxstack 8 L_0000: ldarg.0 L_0001: ldflda valuetype AssemblyTest.MyValType AssemblyTest.MyClass::MyVal2 L_0006: initobj AssemblyTest.MyValType L_000c: ldarg.0 L_000d: call instance void [mscorlib]System.Object::.ctor() L_0012: nop L_0013: ret }.field private valuetype AssemblyTest.MyValType MyVal1.field private valuetype AssemblyTest.MyValType MyVal2 } … 0000 Reference type Value type
Exceptional Cases Case 2: Multiple initializations for the same object Case 2: Multiple initializations for the same object – = 2… Case 3: Initializers can’t get exception Case 3: Initializers can’t get exception – Same objects maybe get exception during Constructor time
Summary 請謹慎選用 Initializers 請謹慎選用 Initializers – 此 Item 雖然很豪邁的叫你直接用 Initializers ,但馬上講了三個例 外。
Initialize Static Class Members with Static Constructors Item 13:
Why we don’t initialize it in constructor? The static member will be reset value every construct time The static member will be reset value every construct time – Singleton pattern is important for static member
How to initialize Static Class Members ? Use Initializers Use Initializers – Singleton pattern Use Static Constructors Use Static Constructors – Singleton pattern – More flexibility – Error recovery here
Summary Static Constructors 與 Initializers 對於初始化 Static Class Members 並沒有優劣之分 Static Constructors 與 Initializers 對於初始化 Static Class Members 並沒有優劣之分 請依據適合的情況使用它們 請依據適合的情況使用它們