在 Effective C# 中建議在宣告成員變數時就直接給予初始值,此作法可避免在程式中使用到未初始化的變數。在宣告時給予初始值,其執行順序比執行此件類別建構子還之前:
class Test
{
int _myIntrger = 5;
public Test()
{
Console.WriteLine(_myIntrger.ToString());
}
}
static void Main(string[] args)
{
Test t = new Test(); // 5
}
但也不是在所有情況下都適合在宣告時直接給予初始值,有 3 種情況應避免使用:
將變數值設為 0 或 null
0 及 null 皆為 C# 的預設初始值,不須額外設置影響效率(此為書中觀點,我覺得寫了有較佳的可讀性)
class Test
{
int myIntrger1;
int myIntrger2 = 0;
object myObj1;
object myObj2 = null;
}
可從 IL 看出 myIntrger2 與 myObj2 配置 0 及 null。
多個建構子
多個建構子代表了建構子本身會帶有不同的參數,若沒處理好則會造成效能問題。
class Test
{
List<int> myList = new List<int>();
public Test()
{
}
public Test(int size)
{
myList = new List<int>(size);
}
}
上述程式若呼叫 Test(int size) 建構子,則 myList 建立兩次實體,第一次產生的實體馬上變成記憶體中的垃圾,應改寫成如下寫法較好:
class Test
{
List<int> myList;
public Test()
{
myList = new List<int>();
}
public Test(int size)
{
myList = new List<int>(size);
}
}
會有Exception的產生
在宣告成員變數時無法使用 try catch 來處理 exception,若沒處理則會在初始化的過程中直接 crash。較好的處理方式為將此初始化的動作移到建構子內進行。
class Test
{
TestA a = new TestA();
public Test()
{
}
}
class TestA
{
public TestA()
{
throw new Exception();
}
}
將初始化動作放到建構子內使用try catch:
class Test
{
TestA a;
public Test()
{
try
{
a = new TestA();
}
catch
{
}
}
}