C#/。NET通過傳遞Array
類型的引用(與C/C++相比,它將所有值直接放在堆棧上,不管是好還是壞)都具有可變參數函數參數。C#中的`params`會不會在每次調用時分配一個新的數組?
在C#世界,這有讓您調用同一個函數以「生」的論點或可重複使用的陣列實例的一個整潔的優勢:
CultureInfo c = CultureInfo.InvariantCulture;
String formatted0 = String.Format(c, "{0} {1} {2}", 1, 2, 3);
Int32 third = 3;
String formatted0 = String.Format(c, "{0} {1} {2}", 1, 2, third);
Object[] values = new Object[] { 1, 2, 3 };
String formatted1 = String.Format(c, "{0} {1} {2}", values);
這意味着產生CIL相當於:
String formatted0 = String.Format(c, "{0} {1} {2}", new Object[] { 1, 2, 3 });
Int32 third = 3;
String formatted0 = String.Format(c, "{0} {1} {2}", new Object[] { 1, 2, third });
Object[] values = new Object[] { 1, 2, 3 };
String formatted1 = String.Format(c, "{0} {1} {2}", values);
這意味着(在非優化的JIT編譯器)每次調用將分配一個新的Object[]
實例 - 儘管在第三個例子你能存儲陣列作爲字段或其他可重複使用的值來消除上的新分配,每調用String.Format
。
但是在官方CLR運行時和JIT中是否進行了任何優化以消除此分配?或者可能數組是特意標記的,以便在執行離開呼叫站點的範圍後立即釋放數組?或者,也許是因爲C#或JIT編譯器知道參數的數量(使用「raw」時)是否可以執行與stackalloc
關鍵字相同的操作,並將該數組放在堆棧上,因此不需要解除分配它?
重新沒有實習生:大不了!如果一個方法在不知道它來自哪裏以及之後會發生什麼變化的情況下改變了一個數組,並且期望它可以正常工作,它就應該得到它。 – jmoreno