تطوير الويب

C# 14 و.NET 10: ميزات اللغة الجديدة في 2026

5 دقائق للقراءة

دروس السلسلة: EF Core 10 · Worker Services .NET 10 · gRPC ASP.NET Core 10 · BenchmarkDotNet .NET 10

C# يتطوّر بإيقاع ثابت: الإصدار 13 رافق .NET 9 في نوفمبر 2024، والـ 14 يُغلق الصف مع .NET 10 LTS الصادر في 11 نوفمبر 2025. معًا، هذان المستويان يُقدّمان موجة من الميزات التي تُغيّر الإنتاجية اليومية ملموسًا: extension members (extension properties، operators، static members)، خصائص بحقل مُولَّد عبر كلمة field، تحويلات ضمنية لـ Span، معاملات params على ReadOnlySpan، أنواع إرجاع partial، تنفيذ ملف .cs مستقل عبر dotnet run. يستعرض هذا الدرس الإسهامات الأكثر هيكلةً لمشروع إنتاج في 2026، مع أمثلة قابلة للاستخدام كما هي.

المتطلبات

  • .NET 10 LTS مُثبَّت (dotnet --version)
  • أساسيات C# (classes، génériques، async)
  • IDE: Visual Studio 2026، JetBrains Rider 2025.3+، أو VS Code + C# Dev Kit
  • الوقت المُقدَّر: 75 دقيقة

الخطوة 1 — Extension members: ما وراء methods

منذ C# 3.0، نُمدّد type بمنهجيات extension methods. C# 14 يُعَمِّم هذه الآلية لكل الأعضاء: properties، operators، indexers، static members. الصياغة تستخدم كتلة extension(T target) التي تُحدّد الهدف. هذه الميزة الأكثر ظهورًا في C# 14.

public static class StringExtensions
{
    extension(string s)
    {
        // Propriété d'extension
        public bool IsNumeric => s.All(char.IsDigit);

        // Indexeur d'extension
        public char this[Index i] => s[i];
    }

    extension(string)
    {
        // Membre statique d'extension
        public static string Empty => string.Empty;
    }
}

// Usage
string id = "12345";
if (id.IsNumeric) Console.WriteLine("numérique");

ثلاث نقاط عملية. property extension للقراءة فقط (لا setter). operators extension تُتيح أخيرًا تعريف +، -، إلخ دون تعديل source type — مفيد لإضافة عمليات لـ type خارجي. static members extension تُتيح إثراء API الثابت لـ type.

الخطوة 2 — Properties بحقل مُولَّد (field keyword)

C# 13 يُقدّم الكلمة contextuelle field في accessors لـ property. تُشير لحقل التخزين المُولَّد تلقائيًا من المُجمِّع، مما يتجنّب تعريف backing field خاص يدويًا.

public class Utilisateur
{
    // Avant C# 13 — il fallait un _email privé séparé
    public string Email
    {
        get => field;
        set => field = value?.Trim().ToLowerInvariant()
                       ?? throw new ArgumentNullException(nameof(value));
    }

    // Validation à l'écriture, lecture transparente
    public int Age
    {
        get;
        set => field = value >= 0 ? value : throw new ArgumentOutOfRangeException();
    }
}

هذه الصياغة تُلغي ضجيج backing fields الخاصة مع الحفاظ على إمكانية إضافة منطق validation، logging، أو إشعار تغيير.

الخطوة 3 — params ReadOnlySpan وتحويلات ضمنية لـ Span

// Allocation zéro pour les appels courts
public static int Somme(params ReadOnlySpan<int> valeurs)
{
    int total = 0;
    foreach (var v in valeurs) total += v;
    return total;
}

// Appels naturels — aucune allocation visible
var s1 = Somme(1, 2, 3);                  // OK
var s2 = Somme(new[] { 4, 5, 6 });        // OK
int[] tableau = { 10, 20, 30, 40 };
var s3 = Somme(tableau[..3]);             // OK conversion implicite C# 14

للمسارات الساخنة (parsing، تسلسل، تحويلات تسلسلات)، هذا التغيير يُلغي مئات آلاف allocations في الثانية. كلفة الذاكرة تنخفض، GC pauses تقصر، latency p99 تتحسّن.

الخطوة 4 — أنواع إرجاع partial وexpanded partial

// Fichier généré par un source generator
public partial class Configuration
{
    public partial string DatabaseUrl { get; }
}

// Fichier écrit à la main
public partial class Configuration
{
    public partial string DatabaseUrl =>
        Environment.GetEnvironmentVariable("DATABASE_URL")
        ?? throw new InvalidOperationException("DATABASE_URL manquant");
}

الميزة: source generator يستطيع إعلان عقد (signature property) يملأه المطوّر على جانب كود المستخدم، أو العكس. مكتبات مثل MediatR، Mapperly، أو ORMs يمكنها الآن توليد properties partial يُثريها كود المستخدم.

الخطوة 5 — تنفيذ ملف .cs مستقل (dotnet run file)

# Créer un fichier minimal
cat > hello.cs <<'EOF'
#!/usr/bin/env dotnet run

using System;
Console.WriteLine(\$"Hello depuis .NET {Environment.Version}");
EOF

# Exécution directe
dotnet run hello.cs
# Ou sur Unix après chmod +x :
./hello.cs

لأداة داخلية CLI من 50 سطرًا، script ترحيل ظرفي، أو تمرين تربوي، هذه الميزة تُلغي مراسم المشروع وتُقارب تجربة C# من Python أو Node.

الخطوة 6 — JIT 2026: AVX-512، ARM SVE2 ومكاسب مجانية

.NET 10 راجع JIT تمامًا لاستثمار AVX-512 (Intel/AMD)، AVX10.2، وARM SVE/SVE2. ملموسًا، دون لمس الكود، runtime يُجَه أكثر العمليات ويُسلّم 15-30% أداء إضافي على الخوادم الحديثة. قياسات Microsoft الرسمية: .NET 10 أسرع 49% في زمن الاستجابة المتوسط من .NET 8، والتسلسل JSON عبر System.Text.Json يكسب 20-40%.

// Aucun changement de code — la vectorisation est transparente
public int SommeRapide(int[] valeurs)
{
    int total = 0;
    foreach (var v in valeurs) total += v;
    return total;
}
// Sur AVX-512, le JIT déroule la boucle et somme 16 entiers par cycle

للتحقق أن vectorisation تُطبَّق على كودك، BenchmarkDotNet يعرض instructions assembleur المُولَّدة مع [DisassemblyDiagnoser].

الخطوة 7 — Pattern matching غني وaliases generics

// Alias générique
using StringDictionary = System.Collections.Generic.Dictionary<string, string>;

public class Cache
{
    private readonly StringDictionary _entries = new();
}

// Pattern matching sur Span
ReadOnlySpan<char> input = "ABC123";
var resultat = input switch
{
    [.., 'X']      => "Termine par X",
    ['A', .., '3'] => "Commence par A, finit par 3",
    _              => "Autre"
};

aliases generics تتجنّب تكرار signatures طويلة في عدة ملفات. pattern matching على Span يُتيح كتابة parsers ad hoc بدون regex لحالات بسيطة.

أخطاء شائعة

العَرَض السبب الحل
خطأ CS9216 على extension TargetFramework < net10.0 <TargetFramework>net10.0</TargetFramework>
field غير مُعرَّف LanguageVersion < 13 <LangVersion>latest</LangVersion>
تحويل ضمني Span مرفوض method بـ overloads غامضة تَوضيح عبر cast صريح
Source generator صامت analyzer غير مُحمَّل Restart VS + dotnet build --no-incremental
Hot reload يكسر على ميزات جديدة Edit and Continue لا يدعم كل شيء Restart يدوي على تغييرات بنيوية
Allocations لا تزال موجودة مع params Span استدعاء عبر reflexion أجبر overload مباشر، تحقّق في assembleur

الأسئلة الشائعة

هل C# 14 يتطلّب .NET 10؟
نعم للجديد. على .NET 8/9، تبقى على C# 12/13.

متى نُرحّل من .NET 8 إلى .NET 10؟
.NET 8 LTS مدعومة حتى نوفمبر 2026. ترحيل إلى .NET 10 LTS (مدعوم حتى نوفمبر 2028) مُوصى به بصيف 2026.

هل extension members تكسر الموجود؟
لا. extension methods الكلاسيكية تبقى مدعومة. كتلة extension صياغة إضافية.

هل field يعمل مع init؟
نعم: public string Nom { get; init => field = value.Trim(); }.

أداء AOT vs JIT في .NET 10؟
AOT يبدأ في < 50 ms لـ 5-15 MB binary، لكن يخسر 10-20% في الأداء المستدام. JIT يبقى أسرع للخدمات طويلة العمل.

مقالات ذات صلة

مشاركة