🚀 چه چیزهایی در C# 14 جدید است
نسخهی C# 14 یکی از مهمترین و تأثیرگذارترین نسخههای منتشر شده در سالهای اخیر است.
بیایید نگاهی بیندازیم به ویژگیهای کلیدی این نسخه: 👇
🧩 Extension Members
ویژگی Extension Members محبوبترین قابلیت جدید من در C# 14 است.
این ویژگی در واقع تکامل مدرن مفهوم Extension Methods محسوب میشود قابلیتی که از نسخهی C# 3.0 معرفی شده بود.
🔹 نحو سنتی Extension Method
قبل از C# 14، برای ایجاد Extension Method باید متدهای استاتیک را با پارامتر this مینوشتید:
public static class StringExtensions
{
public static bool IsNullOrEmpty(this string value)
{
return string.IsNullOrEmpty(value);
}
public static string Truncate(this string value, int maxLength)
{
if (string.IsNullOrEmpty(value) value.Length <= maxLength)
{
return value;
}
return value.Substring(0, maxLength);
}
}
🔹 نحو جدید با کلیدواژهی extension
در C# 14 سینتکس جدیدی معرفی شده که receiver (نوعی که میخواهید آن را گسترش دهید) را از اعضایی که به آن اضافه میکنید جدا میکند.
به جای قرار دادن this روی هر پارامتر متد، حالا میتوانید یک بلوک extension تعریف کنید که فقط یکبار نوع receiver را مشخص میکند:
public static class StringExtensions
{
extension(string value)
{
public bool IsNullOrEmpty()
{
return string.IsNullOrEmpty(value);
}
public string Truncate(int maxLength)
{
if (string.IsNullOrEmpty(value) value.Length <= maxLength)
return value;
return value.Substring(0, maxLength);
}
}
}
در اینجا بلوک extension نوع receiver را به عنوان پارامتر میگیرد. درون این بلوک، میتوانید متدها و propertyها را طوری بنویسید که انگار واقعاً عضو نوع اصلی هستند.
پارامتر value در تمام اعضای داخل بلوک در دسترس است.
نکتهی مهم اینجاست که هر دو سینتکس قدیمی و جدید در نهایت به کد یکسانی کامپایل میشوند، بنابراین رفتارشان دقیقاً مشابه است.
حتی میتوانید هر دو سبک را در یک کلاس استاتیک بهصورت همزمان استفاده کنید. 💡
⚙️ پشتیبانیهای جدید در نحو extension
نحو جدید extension از موارد زیر پشتیبانی میکند:
🧩 Instance methods
🧩 Instance properties
⚡️ Static methods
⚡️ Static properties
💡 Extension Properties
🌟 Extension Properties
ویژگیهای Extension Properties باعث میشن کد شما خواناتر و گویاتر بشه.
به جای فراخوانی متدها، حالا میتونید از propertyهایی استفاده کنید که طبیعیتر بهنظر میان.
برای مثال، وقتی با کالکشنها کار میکنید، معمولاً بررسی میکنید که آیا خالی هستند یا نه.
به جای نوشتن مکرر !items.Any()، میتونید یک property به نام IsEmpty بسازید: 👇
public static class CollectionExtensions
{
extension<T>(IEnumerable<T> source)
{
public bool IsEmpty => !source.Any();
public bool HasItems => source.Any();
public int Count => source.Count();
}
}
public void ProcessOrders(IEnumerable<Order> orders)
{
if (orders.IsEmpty)
{
Console.WriteLine("No orders to process");
return;
}
foreach (var order in orders)
{
// Process order
}
}
💬 در این مثال، حالا میتونید بهصورت طبیعیتر بنویسید:
if (orders.IsEmpty)
بهجای
if (!orders.Any())
نتیجه: کد سادهتر، تمیزتر و خواناتر. ✨
🧠 فیلدهای خصوصی و Caching
درون یک بلوک extension میتونید فیلدها و متدهای خصوصی تعریف کنید درست مثل کلاسهای معمولی.
این قابلیت زمانی مفیده که نیاز دارید محاسبات سنگین (مثل ToList()) فقط یکبار انجام بشن و نتیجهی اون cache بشه.
مثلاً: 👇
public static class CollectionExtensions
{
extension<T>(IEnumerable<T> source)
{
private List<T>? _materializedList;
public List<T> MaterializedList => _materializedList ??= source.ToList();
public bool IsEmpty => MaterializedList.Count == 0;
public T FirstItem => MaterializedList[0];
}
}
در اینجا فیلد خصوصی _materializedList تضمین میکنه که ToList() فقط یکبار اجرا بشه،
صرفنظر از اینکه چند بار به propertyهای مختلف (مثل IsEmpty یا FirstItem) دسترسی داشته باشید.
به این ترتیب، performance بهشکل محسوسی بهبود پیدا میکنه. ⚡️