C# 12 به همراه روش جدیدی برای آغاز مجموعهها است که با آرایهها، Spanها و هر نوعی که آغازگرهای مجموعهها را بپذیرد، کار میکند. همچنین اپراتور جدیدی را هم به نام spread operator به صورت .. به زبان #C اضافه کردهاست که امکان سادهتر ترکیب مجموعهها را میسر میکند.
آغاز سادهتر مجموعهها با کمک Collection Expressions
تا پیش از C# 12 برای آغاز یک آرایه میتوان از روش زیر استفاده کرد که در آن نوع آرایه از طریق نوع اعضای آن حدس زده میشود:
var numbers1_CS11 = new[] { 1, 2, 3 };
که در حقیقت ساده شدهی تعریف اصلی زیر است:
var numbers1_CS_11 = new int[] { 1, 2, 3 };
در C# 12، میتوان این تعاریف را به کمک collection expressions، خلاصهتر هم کرد:
int[] numbers1_CS12 = [ 1, 2, 3 ];
که در اینجا، {}ها به [] تبدیل شدهاند و ذکر نوع آرایه، ضروری است (یعنی نمیتوان از var جهت تعریف آنها استفاده کرد)؛ در غیراینصورت با خطای زیر متوقف میشویم:
error CS9176: There is no target type for the collection expression.
یک collection expression و یا collection literals، به مجموعهای از عناصر گفته میشود که بین دو براکت [] قرار میگیرند.
نمونهی دیگر آن کار با Spanها است که نمونه کد C# 11 آن:
Span<string> span1_CS11 = new string[] { "AC", "AL" };
در C# 12 به صورت زیر خلاصه میشود:
Span<string> span1_CS12 = [ "AC", "AL" ];
و در اینجا امکان کار با ReadOnlySpanها هم وجود دارد:
ReadOnlySpan<string> readOnlySpan_CS12 = [ "Africa", "Asia", "Europa"];
مثال دیگر، نحوهی آغاز آرایههای چندبعدی است:
int[][] array2D_CS11 =
{
new int[] { 2002, 2006, 2010},
new int[] { 2014, 2018},
new int[] { 2022, 2026, 2030}
};
که در C# 12 به صورت خلاصهی زیر قابل بیان است:
int[][] array2D_CS12 =
[
[2002, 2006, 2010],
[2014, 2018],
[2022, 2026, 2030]
];
و یا حتی این مورد را در مورد نحوهی آغاز Listهای پیش از C#12
List<string> list_CS11 = new List<string> { "Item 1", "Item 2" };
نیز میتوان بکار گرفت:
List<string> list_CS12 = [ "Item 1", "Item 2" ];
در کل همانطور که مشاهده میکنید، این تغییر، تغییر مثبتی است و حجم قابل ملاحظهای از کدها را کاهش داده و خواندن آنها را نیز سادهتر میکند.
یک نکته: روش ساده شدهی آغاز یک لیست با مجموعهای خالی در C# 12 به صورت زیر است:
// Before C#12
List<User> users = new List<User>();
// or
var users = new List<User>();
// or
List<User> user = new();
// C#12
List<User> users = [];
اضافه شدن spread operator به زبان #C
اگر پیشتر با زبان JavaScript کار کرده باشید، با spread operator هم آشنایی دارید. کار آن ساده سازی یکی کردن مجموعهها و یا افزودن سادهتر عناصری به آنها است و .. بالاخره به زبان #C هم راه پیدا کردهاست! برای مثال دو آرایهی زیر را درنظر بگیرید:
int[] numbers1_CS12 = [ 1, 2, 3 ];
int[] numbers2_CS12 = [ 4, 5, 6 ];
در C# 12 برای یکی کردن آنها میتوان از spread operator به صورت زیر استفاده کرد:
int[] allItems = [ ..numbers1_CS12, ..numbers2_CS12 ];
Spread به معنای «پخش کردن»/«گسترده کردن»/«باز کردن» هست. برای مثال در اینجا، اعضای دو آرایه را داخل یک آرایهی جدید، پخش کردهایم!
اگر در نگارشهای قبلی #C بخواهیم چنین کاری را انجام دهیم، یک روش آن به صورت زیر است:
int[] allItems_CS11 = numbers1_CS12.Concat(numbers2_CS12).ToArray();
که ... نگارش C# 12 آن کارآیی بیشتری دارد؛ چون تعداد بار اختصاص حافظهی آن کمتر است. در C# 12، هنگام استفاده از spread operator، کار کپی کردن اطلاعات صورت نمیگیرد و همچنین طول نهایی مجموعهی حاصل دقیقا مشخص میشود که این مورد از چندین بار تخصیص حافظه برای چسباندن آرایههای مختلف به هم جلوگیری میکند.
همچنین اپراتور پخش کردن، قابلیت قرارگرفتن در کنار سایر اعضای یک آرایه را هم به سادگی و با خوانایی بیشتری به همراه دارد:
int[] join = [..a, ..b, ..c, 6, 5];
به علاوه محدودیتی در مورد نوع مجموعهی بکار گرفته شده نیز در اینجا وجود ندارد. برای نمونه در مثال زیر، یک آرایه، یک Span و یک لیست، با هم یکی شدهاند:
int[] a =[1, 2, 3];
Span<int> b = [2, 4, 5, 4, 4];
List<int> c = [4, 6, 6, 5];
List<int> join = [..a, ..b, ..c, 6, 5];
و مثالی دیگر، نحوهی سادهی تعریف لیستی از tuples است:
List<(string, int)> otherScores = [("Dave", 90), ("Bob", 80)];
و سپس باز کردن آن داخل آرایهای از tuples:
(string name, int score)[] scores = [("Alice", 90), ..otherScores, ("Charlie", 70)];