大家都知道在C++中,我們可以為方法的參數指定一個預設值,像這樣:
void foo(int i = 100);
當我們以這種形式調用方法的時候: foo(); 實際上參數i被賦於了預設值,所以相當於調用了foo(100);
然而在C#中是不支援參數的預設值的,那麼如果我們要用到類似的功能應該怎麼實現呢?考慮下面這個例子:
class Buffer
{
public Buffer(int bufferSize = 100) //Compile Error
{
buf = new int [bufferSize];
}
private int[] buf;
}
首先當然要為Buffer提供一個無參的建構函式重載:
class Buffer
{
public Buffer(int bufferSize)
{
buf = new int[bufferSize];
}
public Buffer():this(100)
{
}
private int[] buf;
}
但這個方法有一個問題就是我們把Buffer的預設大小hard-coding到了代碼裡,這有兩個弊端,一是損害了代碼的可讀性,二是用以上方法,如果Buffer有多個重載的建構函式都用到bufferSize的預設值,一旦你要修改預設值的大小,不得不同時修改多處程式,一旦漏掉了其中的一個,說不定就麻煩大了。
所以,正確的方法是為bufferSize提供一個const的預設值:
class Buffer
{
private const int defaultBufferSize = 100;
public Buffer(int bufferSize)
{
buf = new int[bufferSize];
}
public Buffer():this(defaultBufferSize)
{
}
private int[] buf;
}
觀察編譯器為public Buffer()產生的il代碼
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 20 (0x14)
.maxstack 2
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ldarg.0
IL_0007: ldc.i4.s 100 //100即為defaultBufferSize的值
IL_0009: newarr [mscorlib]System.Int32
IL_000e: stfld int32[] Buffer::buf
IL_0013: ret
} // end of method Buffer::.ctor
defaultBufferSize的值在相應的調用處被替換成了字面常量(這其實也就是const成員的特性),所以使用defaultBufferSize不會影響public Buffer()的執行效率。而由於const成員隱含了static的特性,所以一個Buffer類只有一個defaultBufferSize的變數,效能的影響也是很小的。
我們可以看到.net 類庫中的許多類都使用了這種方法