مقدمة: لماذا الأخطاء أمر طبيعي
رحلة كل مطور تبدأ بالأخطاء. لغة C# (.NET) هي لغة قوية ومكتوبة بشدة (strongly typed) تغفر أقل من اللغات الديناميكية، ولكن في المقابل تقدم الموثوقية والأداء. في هذه المقالة، سنقوم بتحليل أكثر 4 مطبات شيوعًا التي يتعثر فيها المبتدئون ونوضح كيفية تجنبها. ستكون هذه المقالة مفيدة لكل من يبدأ في تعلم C# ولمن يريد تحديث معرفته.
1. تجاهل null واستثناء NullReferenceException
الخطأ الأكثر شيوعًا في C# هو NullReferenceException. يحدث عندما تحاول الوصول إلى عضو (member) في كائن قيمته null.
مثال على المشكلة
string text = null;int length = text.Length; // خطأ! NullReferenceExceptionغالبًا ما ينسى المبتدئون التحقق من القيم المعادة من الدوال، أو يعتمدون على افتراض أن الكائن موجود بالتأكيد.
كيف تفعل ذلك بشكل صحيح
- تحقق دائمًا من الكائنات للتأكد من أنها ليست
nullقبل استخدامها. - استخدم العوامل
?.(الشرطي للقيمة الخالية) و??(دمج القيم الخالية).
string text = GetText(); // قد يعيد nullint? length = text?.Length; // إذا كان text == null، فإن length ستكون nullint safeLength = text?.Length ?? 0; // إذا كانت null، فالقيمة 0Console.WriteLine(safeLength);أيضًا في C# 8.0+، ظهرت أنواع المراجع القابلة للقيمة الخالية (nullable reference types)، والتي يتم تفعيلها عبر #nullable enable. إنها تجبرك على تحديد ما إذا كان المتغير يمكن أن يكون null بشكل صريح، وتحذر من المشاكل المحتملة في وقت الترجمة.
2. الاستخدام الخاطئ لـ var وفقدان قابلية القراءة
الكلمة المفتاحية var تسمح للمترجم (compiler) بتحديد نوع المتغير بنفسه. هذا مريح، لكن المبتدئين غالبًا ما يفرطون في استخدامها، مما يجعل الكود غير قابل للقراءة.
مثال على كود سيء
var data = GetData();var result = Process(data);var output = Transform(result); // ما الأنواع؟ غير واضح.بعد شهر، لن تتمكن أنت (أو زميلك) من فهم نوع data بسرعة دون النظر إلى تعريف الدالة.
متى تستخدم var
- عندما يكون النوع واضحًا من الجانب الأيمن (مثل:
var list = new List<int>();) - عند العمل مع الأنواع المجهولة (anonymous types) واستعلامات LINQ.
// جيد: النوع واضحvar numbers = new List<int> { 1, 2, 3 };
// جيد: نوع مجهولvar person = new { Name = "John", Age = 30 };
// سيء: النوع غير واضحvar config = LoadConfiguration(); // الأفضل: Configuration config = LoadConfiguration();القاعدة الذهبية: استخدم var فقط عندما تحسن قابلية القراءة، وليس عندما تقللها.
3. ابتلاع الاستثناءات وكتل catch الفارغة
العديد من المبتدئين، عند مواجهة الاستثناءات، يكتبون كتلة catch فارغة أو ببساطة يخرجون رسالة دون تحليل الخطأ. هذا يجعل البرنامج غير مستقر ويعقد عملية التصحيح.
مثال على نمط سيء
try{ int.Parse("not a number");}catch (Exception){ // لا تفعل شيئًا — تم "ابتلاع" الخطأ}سيستمر التطبيق في العمل، لكن في حالة غير صحيحة. لن يعرف المستخدم بالمشكلة، وقد تتلف البيانات.
كيف تتعامل مع الاستثناءات بشكل صحيح
- لا تلتقط الاستثناء العام
Exceptionإلا إذا كنت تخطط لمعالجة جميع أنواع الأخطاء. - التقط فقط الاستثناءات التي يمكنك معالجتها (مثل:
FormatException,FileNotFoundException). - استخدم
finallyلتحرير الموارد (الملفات، الاتصالات). - سجل الأخطاء (Log errors).
try{ int number = int.Parse(userInput);}catch (FormatException ex){ // سجل الخطأ وأبلغ المستخدم