⚙️ Static Extension Members
قابلیت Static Extensions به شما اجازه میدهد که متدهای کارخانهای (Factory Methods) یا توابع کمکی (Utility Functions) را بهصورت استاتیک به یک نوع (Type) اضافه کنید، نه به instance آن.
برای ایجاد static extensions، از extension استفاده کنید بدون اینکه پارامتر گیرنده (Receiver Parameter) را نامگذاری کنید: 👇
public static class ProductExtensions
{
extension(Product)
{
public static Product CreateDefault() =>
new Product
{
Name = "Unnamed Product",
Price = 0,
StockQuantity = 0,
Category = "Uncategorized",
CreatedDate = DateTime.UtcNow
};
public static bool IsValidPrice(decimal price) =>
price >= 0 && price <= 1000000;
public static string DefaultCategory => "General";
}
}
حالا میتونید این اعضای استاتیک رو مستقیماً روی خود نوع (Type) فراخوانی کنید:
var product = Product.CreateDefault();
if (Product.IsValidPrice(999.99m))
{
product.Price = 999.99m;
}
✨ این ویژگی باعث میشه که کلاسها تمیزتر و سازمانیافتهتر باشن، مخصوصاً برای ایجاد factory یا helper methods.
🤖 Null-Conditional Assignment
در C# 14، عملگرهای Null-Conditional
یعنی ?. و ?[ ] حالا میتونن برای عمل انتساب (assignment) هم استفاده بشن، نه فقط برای دسترسی به اعضا.
🔸 در نسخههای قبلی #C، باید قبل از انتساب، بهصورت دستی null-check انجام میدادید:
if (user is not null)
{
user.Profile = LoadProfile();
}
اما حالا میتونید همون کار رو خیلی تمیزتر بنویسید: 👇
user?.Profile = LoadProfile();
🧠 این نحو جدید، هم کوتاهتره و هم با نحو null-conditional در خواندن مقدارها (reading values) سازگاری بیشتری داره.
🧩 The field Keyword
کلمهی کلیدی field در C# 14 یکی از ویژگیهای کاربردی جدیده که نیاز به تعریف فیلدهای پشتیبان (backing fields) دستی رو در بسیاری از سناریوهای معمولی حذف میکنه.
🔹 قبلاً باید فیلد خصوصی رو خودتون تعریف میکردید:
public class Record
{
private string _msg;
public string Message
{
get => _msg;
set => _msg = value ?? throw new ArgumentNullException(nameof(value));
}
}
اما حالا با field میتونید مستقیماً به فیلد تولیدشده توسط کامپایلر اشاره کنید:
public class Record
{
public string Message
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(value));
}
}
💡 میتونید از field در هر access modifier مثل get، set یا init استفاده کنید.
اگر قبلاً در کدتون متغیری به نام field داشتید، میتونید برای جلوگیری از تداخل از @field یا this.field استفاده کنید.
⚡️ کاربرد عملی: Lazy Initialization و مقدارهای پیشفرض
کلمهی field برای lazy initialization یا تنظیم مقدارهای پیشفرض عالیه: 👇
public class ConfigReader
{
public string FilePath
{
get => field ??= "data/config.json";
set => field = value;
}
public Dictionary<string, string> ConfigValues
{
get => field ??= new Dictionary<string, string>();
set => field = value;
}
}
🧠 به این ترتیب، نیازی نیست فیلدهای پشتیبان جداگانه برای FilePath و ConfigValues تعریف کنید همهچیز تمیزتر و خلاصهتر میشه.
🪄 Lambda Parameters with Modifiers
در C# 14 حالا میتونید از modifierهایی مثل out، ref، in، scoped و ref readonly در پارامترهای lambda استفاده کنید، بدون اینکه مجبور باشید نوع (type) رو بهصورت کامل مشخص کنید.
🔸 در نسخههای قبلی، باید نوع کامل پارامترها رو مینوشتید:
delegate bool TryParse<T>(string text, out T result);
TryParse<int> parse = (string text, out int result) => Int32.TryParse(text, out result);
اما حالا، کامپایلر نوعها رو خودش استنتاج (infer) میکنه و کد شما خلاصهتر میشه: 👇
delegate bool TryParse<T>(string text, out T result);
TryParse<int> parse = (text, out result) => Int32.TryParse(text, out result);
🔹 این ویژگی، هم کد رو مختصرتر میکنه، هم type-safety حفظ میشه.
نتیجه؟ نوشتن delegateها و lambdaهای پیچیده بسیار سادهتر از قبل خواهد بود. 🚀