0Pricing
C# Academy · درس

ترحيل قاعدة شيفرة إلى NRT

طبّقوا استراتيجية ترحيل مرحلية: فعّلوا التحذيرات، وعلّقوا APIs، وأصلحوا المشكلات، وتجنّبوا النتائج الإيجابية الكاذبة.

ترحيل قاعدة شيفرة إلى NRT درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 4 دروس في المجموع.

تحدي الترحيل

يؤدي تمكين NRT في قاعدة تعليمات برمجية موجودة عادةً إلى ظهور مئات التحذيرات. ويُعد اتباع نهج شامل دفعة واحدة أمرًا محفوفًا بالمخاطر. بدلًا من ذلك، استخدم ترحيلًا مرحليًا: فعّل التحذيرات تدريجيًا، وأصلحها ملفًا تلو الآخر، ولا تسمح أبدًا بفقدان الزخم.

الخطوة 1: تمكين التحذيرات فقط

ابدأ باستخدام <Nullable>warnings</Nullable> بدلًا من enable. فهذا يفعّل التحذيرات من دون التعامل مع التعليمات البرمجية غير الموسومة على أنها أخطاء، مما يوفر نقطة بداية آمنة.

<!-- Phase 1: warnings only, no breaking change -->
<PropertyGroup>
  <Nullable>warnings</Nullable>
</PropertyGroup>

<!-- Phase 2: full enable per file as you migrate -->
<!-- Phase 3: switch to enable globally when done -->

الخطوة 2: التمكين لكل ملف

أضف #nullable enable في أعلى كل ملف أثناء العمل عليه. وهكذا تقتصر التغييرات على الملفات التي تعدّلها فعليًا، وتصبح مراجعتها أسهل.

#nullable enable
// Now this file has full NRT analysis

public class OrderService
{
    private readonly IOrderRepository _repo;
    // Compiler now warns about uninitialized non-nullable fields,
    // unsafe dereferences, and assignment to non-nullable

    public OrderService(IOrderRepository repo) => _repo = repo;
}

// Other files without #nullable enable are still unchecked

تصنيف التحذيرات

تنقسم التحذيرات إلى فئتين: يمكن كبتها بأمان (كيانات ORM والحقول المحقونة عبر DI) وأخطاء حقيقية (قيم null يتم إلغاء الإشارة إليها فعليًا). ميّز بين هذه الحالات قبل كبت أي تحذير.

// Category 1: safe to suppress with null!
// EF Core navigation properties — set by EF, never null in practice
public class Order
{
    public Customer Customer { get; set; } = null!;
}

// Category 2: real bug — must fix
public string GetFullName()
{
    return FirstName + " " + LastName; // LastName was string? -- BUG!
}

إصلاح تحذير المُنشئ CS8618

يظهر CS8618 عندما لا تُعيَّن خاصية غير قابلة لـ null في المُنشئ. والإصلاح المفضّل هو طلب قيمتها في المُنشئ. استخدم = null! فقط للقيم التي يعيّنها إطار العمل.

// BEFORE (CS8618)
public class Product
{
    public string Name { get; set; }   // warning
    public Category Category { get; set; } // warning
}

// AFTER — constructor required:
public class Product
{
    public string Name { get; set; }
    public Category Category { get; set; }

    public Product(string name, Category category)
    {
        Name = name;
        Category = category;
    }
}

التعامل مع واجهات API القديمة

قد لا تكون واجهات API التابعة لجهات خارجية أو القديمة موسومة بالتعليقات التوضيحية. وتكون أنواع القيم التي تعيدها oblivious (فلا هي قابلة لـ null ولا غير قابلة لـ null). أسنِد نتائجها إلى متغيرات قابلة لـ null لتكون صريحًا بشأن ذلك.

// Legacy API returns 'string' but might be null (oblivious type)
string? legacyResult = OldLibrary.GetValue(); // store as nullable
if (legacyResult is null) return;

// Or convert at the boundary:
string safe = OldLibrary.GetValue() ?? "";

// For third-party types, check if they have NRT annotations:
// NuGet packages often add nullable annotations in newer versions

استخدام #pragma لكبت تحذيرات محددة

عندما يكون التحذير نتيجة إيجابية زائفة فعلًا ويبدو استخدام = null! مزعجًا، استخدم #pragma warning disable مع حصر نطاقه في السطر المحدد.

// Suppress for a specific case with explanation:
#pragma warning disable CS8618 // ORM populates this via reflection
public DbSet<Product> Products { get; set; }
#pragma warning restore CS8618

// Or inline with a comment:
public DbSet<Order> Orders { get; set; } = null!; // set by EF Core

معاملة تحذيرات NRT كأخطاء

بعد إصلاح جميع التحذيرات في ملف، أضف <WarningsAsErrors>Nullable</WarningsAsErrors> (أو استخدم فرض ذلك في CI) لمنع التراجع؛ فأي مشكلة جديدة تتعلق بالقيم القابلة لـ null ستؤدي إلى فشل عملية البناء.

<!-- After full migration: treat nullable warnings as build errors -->
<PropertyGroup>
  <Nullable>enable</Nullable>
  <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
  <!-- Or selectively: -->
  <!-- <WarningsAsErrors>CS8600;CS8602;CS8603</WarningsAsErrors> -->
</PropertyGroup>

إضافة التعليقات التوضيحية إلى واجهات API العامة

عند استخدام الآخرين لمكتبتك، تصبح التعليقات التوضيحية لـ NRT جزءًا من عقد واجهة API العامة. أعد T? عندما يمكن أن تكون النتيجة null، وأعد T عندما تكون مضمونة القيمة.

public interface IProductService
{
    // Contract: FindById MAY return null, GetById never does
    Product? FindById(int id);
    Product  GetById(int id);  // throws if not found

    // Collection: never null (may be empty)
    IReadOnlyList<Product> GetAll();

    // String: may be empty but not null
    string GetSummary(int id);
}

مقاييس الترحيل وتتبعها

تتبّع التقدم من خلال عدّ الملفات التي تحتوي على #nullable enable، أو بتشغيل dotnet build 2>&1 | grep CS86 في CI. حدّد تاريخًا مستهدفًا لإكمال ترحيل المشروع بأكمله.

# Count NRT warnings in current build
dotnet build 2>&1 | grep -c 'CS860[0-9]\|CS861[0-9]\|CS862[0-9]'

# List files still missing #nullable enable
grep -rL '#nullable enable' src/ --include='*.cs'

# Track in CI: fail if warning count increases
# Set a budget: warnings <= N, where N decreases each sprint

اختبار سريع

ماذا يعني التعيين = null! في خاصية غير قابلة لـ null؟

مراجعة: الترحيل إلى NRT

أهم النقاط:

  • استخدم الترحيل المرحلي: وضع التحذيرات ← التمكين لكل ملف ← التمكين العام
  • ميّز بين الأخطاء الحقيقية (أصلحها) وأنماط ORM/DI (استخدم = null!)
  • أصلح CS8618 بطلب القيم في المُنشئات، لا بكبت التحذير
  • أسنِد نتائج واجهات API القديمة إلى متغيرات T? لتكون صريحًا بشأن إمكانية null
  • عامِل تحذيرات القيم القابلة لـ null كأخطاء في CI لمنع التراجع
  • تصبح واجهات API العامة المزوّدة بالتعليقات التوضيحية عقودًا واضحة للمستهلكين

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

هل درس «ترحيل قاعدة شيفرة إلى NRT» مجاني؟

نعم — نص درس «ترحيل قاعدة شيفرة إلى NRT» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 4 دروس في المجموع.

ماذا ستتعلم في «ترحيل قاعدة شيفرة إلى NRT»؟

طبّقوا استراتيجية ترحيل مرحلية: فعّلوا التحذيرات، وعلّقوا APIs، وأصلحوا المشكلات، وتجنّبوا النتائج الإيجابية الكاذبة. تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟

لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «ترحيل قاعدة شيفرة إلى NRT»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟

نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. تمكين NRT وفهمه
  2. التعليقات التوضيحية: ? و! وMaybeNull وNotNull
  3. العوامل Null-Conditional وNull-Coalescing
  4. ترحيل قاعدة شيفرة إلى NRT
← العودة إلى C# Academy