淺談 C# 13 中的 Params 集合
前言
在 C# 13 中,params 的改進使其從可變數量的數組參數升級為可變數量的集合類型參數。這一改進通過支持高性能集合類型(如Span<T>,ReadOnlySpan<T>)和簡化調用語法,顯著提升了代碼的靈活性和效率。
params的適用場景
params適用于參數個數動態變化的場景,例如日志、數學計算或格式化輸出等,減少冗余代碼,增強方法通用性。
C# 13 的改進與舊版本對比
在 C# 13 之前:
params 僅支持一維數組(如params int[] list、params object[] list)。調用方法時需顯式傳遞數組或數組元素類型的參數的逗號分隔列表。
在 C# 13 中:
params 修飾符并不局限于數組類型。 現在可以將 params 用于任何已識別的集合類型,包括 System.Span<T>、System.ReadOnlySpan<T>,以及那些實現 System.Collections.Generic.IEnumerable<T> 并具有 Add 方法的類型。 除了具體類型外,還可以使用接口 System.Collections.Generic.IEnumerable<T>、System.Collections.Generic.IReadOnlyCollection<T>、System.Collections.Generic.IReadOnlyList<T>、System.Collections.Generic.ICollection<T>和 System.Collections.Generic.IList<T>。
注意事項
在方法聲明中的 params 關鍵字之后不允許有任何其他參數,并且在方法聲明中只允許有一個 params 關鍵字。
性能基準測試
下面我們使用一個數據求和場景,對C# 13 之前和C# 13 中的改進方式使用BenchmarkDotNet做一下性能基準測試對比:
[MemoryDiagnoser]//記錄內存分配情況
[MarkdownExporter, AsciiDocExporter, HtmlExporter, CsvExporter, RPlotExporter]
public class ParamsBenchmark
{
private List<int> dataList = new();
/// <summary>
/// 初始化測試數據
/// 如創建大型數據集、分配內存資源等,避免在每次基準測試迭代中重復初始化帶來的性能干擾
/// </summary>
[GlobalSetup]
public void Setup()
{
dataList = new List<int> { 1, 2, 3, 4, 5, 6, 7, 9, 10, 22, 55, 66, 88, 44, 66, 33, 77, 54, 24, 8789, 24, 54, 244, 377, 26, 99, 888, 1000 };
}
[Benchmark]
public int CalculateOldSum()
{
return OldSumArray(dataList.ToArray());
}
[Benchmark]
public int CalculateNewSumList()
{
return NewSumList(dataList);
}
/// <summary>
/// C# 13 之前
/// </summary>
/// <param name="datas">datas</param>
/// <returns></returns>
public int OldSumArray(params int[] datas)
{
return datas.Sum();
}
/// <summary>
/// C# 13 中
/// </summary>
/// <param name="datas">datas</param>
/// <returns></returns>
public int NewSumList(params List<int> datas)
{
return datas.Sum();
}
}
基準測試報告
圖片
- Mean: 所有測量值的算術平均值。
- Error: 99.9% 置信區間的一半。
- StdDev: 所有測量值的標準差。
- Gen0: 第 0 代 GC 每 1000 次操作收集一次。
- Allocated: 每次操作分配的內存(僅托管內存,包含所有內容,1KB = 1024B)。
最后總結
綜上所述C# 13 中的 params 集合變得類型更靈活,滿足更復雜的應用場景,并且性能得到了進一步的提升。