مراجعة كود C#: ليست مجرد إجراء شكلي، بل إنقاذ للتطبيق
\n\nهل سبق لك أن رأيت كودًا يعمل ولكنك تتمنى لو أغمضت عينيك عنه؟ "أرقام سحرية"، حلقات متداخلة، async void و null في غير محله. مراجعة كود C# ليست مجرد إجراء بيروقراطي، بل هي خط الدفاع الأخير قبل أن يصل الخلل إلى الإنتاج. أو الأسوأ من ذلك، قبل أن يضطر زملاؤك إلى صيانة هذا الكود وهم يلعنون كاتبه.
في هذه المقالة، سنستعرض ما يجب التركيز عليه حقًا عند مراجعة كود C#. لا ماء، فقط حالات عملية، أنماط سيئة وأمثلة. إذا كنت مطورًا مبتدئًا، فهذه قائمة فحصك. وإذا كنت خبيرًا، فجدّد معلوماتك. هيا بنا.
\n\n1. Null: العدو الأكبر لمطور C#
\n\nاستثناء NullReferenceException الشهير هو سبب ملايين ليالي الأرق. أول ما نفحصه في مراجعة الكود: الحماية من null.
ما الذي يجب أن يثير الشك؟
\n- \n
- عدم وجود فحص لـ
nullقبل الوصول إلى الخصائص. \n - إرجاع
nullمن دوال يُتوقع منها إرجاع مجموعة. \n - تجاهل سياقات nullable (
#nullable enable). \n
مثال سيء:
\npublic string GetUserName(User user)\n{\n return user.Name.ToUpper(); // user قد يكون null!\n\nمثال جيد (C# 8+):
\npublic string GetUserName(User? user)\n{\n return user?.Name?.ToUpper() ?? "غير معروف";\n}\n\nنصيحة لمراجعة الكود: اطلب تفعيل Nullable في المشاريع الجديدة. هذا ليس مجرد موضة، بل ينقذك من أخطاء سخيفة. مراجعة كود C# بدون فحص nullable كالقيادة بدون حزام أمان.
2. البرمجة غير المتزامنة: async/await بدون أخطاء
\n\nالبرمجة غير المتزامنة في C# أداة قوية، لكن استخدامها الخاطئ يحولها إلى قنبلة موقوتة. في المراجعة، نفحص ثلاثة أخطاء رئيسية.
\n\nالخطأ الأول: async void
\nلا يمكن تتبع دوال async void — الاستثناء سينتقل إلى الخيط الرئيسي ويقتل العملية. مسموح بها فقط لمعالجات الأحداث (مثل أزرار WinForms).
مثال سيء:
\npublic async void LoadDataAsync()\n{\n var data = await _service.GetDataAsync(); // الخطأ سيقتل العملية\n}\n\nمثال جيد:
\npublic async Task LoadDataAsync()\n{\n var data = await _service.GetDataAsync();\n}\n\nالخطأ الثاني: حظر الكود غير المتزامن
\nاستخدام .Result أو .Wait() في سياق غير متزامن هو طريق مؤكد للتوقف التام (deadlock).
مثال سيء:
\nvar result = _service.GetDataAsync().Result; // deadlock في تطبيقات الواجهة\n\nمثال جيد:
\nvar result = await _service.GetDataAsync();\n\nالخطأ الثالث: عدم وجود CancellationToken
\nيجب أن تكون العمليات الطويلة قابلة للإلغاء. إذا لم تحتوِ دالة على CancellationToken، اسأل الكاتب: "ماذا سيحدث إذا أغلق المستخدم الصفحة؟"
3. LINQ: جمال أم موت بطيء؟
\n\nLINQ أنيق. لكن مراجعة الكود غالبًا ما تكشف أن وراء هذا الأناقة O(n²) أو مرور متعدد على المجموعة.
\n\nأخطاء شائعة في مراجعة كود C# مع LINQ:
\n- \n
- المرور المتعدد: استخدام
.Count() > 0ثم.First()— مروران. استخدم.Any()و.FirstOrDefault(). \n - نسيان ToList(): التحميل الكسول قد يؤدي إلى تنفيذ الاستعلام بعد إغلاق DataReader. \n
- Where + Select = تكرار: إذا كان يمكن استخدام
SelectManyواحد، فاستخدمه. \n
مثال يجب أن يثير علامة حمراء:
\nvar result = l