الاستثناءات المخصصة وتصميم الأخطاء
أنشئ استثناءات مخصصة صغيرة، واختر الأنواع المدمجة المناسبة (ArgumentException وInvalidOperationException)، وأضف السياق باستخدام InnerException.
الاستثناءات المخصصة وتصميم الأخطاء درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 2 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 3 دروس في المجموع.
الغرض والأهداف
الهدف: جعل الأخطاء واضحة وقابلة للالتقاط.
- استخدم نوعًا محددًا لكل حالة فشل محددة
- رسالة جيدة مع InnerException لتوفير السياق
- فضّل الأنواع المضمنة عندما تكون مناسبة
نوع استثناء مخصص
اشتق من Exception، وأنهِ الاسم بـ Exception، وأضف المُنشئات القياسية. أرفق بيانات صغيرة ومفيدة.
using System;
// Custom, specific to our domain
public sealed class ConfigNotFoundException : Exception
{
public string Key { get; private set; }
public ConfigNotFoundException(string key)
: base("Config key not found: " + key)
{
Key = key;
}
public ConfigNotFoundException(string key, Exception inner)
: base("Config key not found: " + key, inner)
{
Key = key;
}
}
public class Program
{
public static void Main(string[] args)
{
try
{
throw new ConfigNotFoundException("ApiUrl");
}
catch (ConfigNotFoundException ex)
{
Console.WriteLine(ex.Message);
}
}
}
استخدام InnerException لتوفير السياق
غلّف الاستثناءات منخفضة المستوى باستثناء خاص بالمجال واضبط InnerException للاحتفاظ بالسبب الجذري.
using System;
using System.IO;
public sealed class ConfigNotFoundException : Exception
{
public string Key { get; private set; }
public ConfigNotFoundException(string key, Exception inner)
: base("Config key not found: " + key, inner) { Key = key; }
}
public static class Config
{
public static string Load(string path, string key)
{
try
{
string[] lines = File.ReadAllLines(path); // may throw
for (int i = 0; i < lines.Length; i++)
{
int idx = lines[i].IndexOf("=");
if (idx > 0 && lines[i].Substring(0, idx) == key)
return lines[i].Substring(idx + 1);
}
throw new ConfigNotFoundException(key, null);
}
catch (IOException io)
{
// Wrap low-level error with domain meaning
throw new ConfigNotFoundException(key, io);
}
}
}
public class Program
{
public static void Main(string[] args)
{
try
{
Console.WriteLine(Config.Load("missing.cfg", "ApiUrl"));
}
catch (ConfigNotFoundException ex)
{
Console.WriteLine("Top: " + ex.Message);
if (ex.InnerException != null)
Console.WriteLine("Inner: " + ex.InnerException.GetType().Name);
}
}
}
اختيار الأنواع المضمنة أولًا
استخدم الأنواع المضمنة للمشكلات الشائعة: ArgumentNullException، ArgumentOutOfRangeException، FormatException، InvalidOperationException، وغير ذلك.
using System;
public static class MathUtil
{
public static int Divide(int a, int b)
{
if (b == 0) throw new DivideByZeroException();
return a / b;
}
public static int ParsePositive(string text)
{
if (text == null) throw new ArgumentNullException("text");
int value = int.Parse(text); // may throw FormatException
if (value <= 0) throw new ArgumentOutOfRangeException("text", "must be > 0");
return value;
}
}
public class Program
{
public static void Main(string[] args)
{
try { Console.WriteLine(MathUtil.ParsePositive("-1")); }
catch (ArgumentOutOfRangeException ex) { Console.WriteLine("Range: " + ex.ParamName); }
}
}
الاستثناءات مقابل الحواجز
استخدم الاستثناءات للحالات الاستثنائية. أما حالات الفشل المتوقعة، ففضّل حواجز TryX أو رموز الإرجاع.
using System;
public static class Parser
{
// BAD: using exceptions for expected cases
public static int ParseOrThrow(string s)
{
return int.Parse(s); // will throw often for user input
}
// GOOD: guard-check pattern for expected failure
public static bool TryParsePositive(string s, out int value)
{
value = 0;
int tmp;
if (!int.TryParse(s, out tmp)) return false;
if (tmp <= 0) return false;
value = tmp;
return true;
}
}
public class Program
{
public static void Main(string[] args)
{
int v;
if (Parser.TryParsePositive("12", out v))
Console.WriteLine("OK " + v);
else
Console.WriteLine("Invalid");
}
}
قائمة التحقق من تصميم الأخطاء
قائمة التحقق:
- اختر نوعًا مضمنًا متى أمكن.
- وإلا، أنشئ CustomException صغيرًا مع المُنشئات القياسية.
- أرفق InnerException للحفاظ على السبب الجذري.
- استخدم الاستثناءات للحالات غير المتوقعة؛ واستخدم TryX لحالات الفشل المتوقعة.
تصميم الاستثناءات المخصصة
مراجعة
مراجعة: فضّل الاستثناءات المضمنة؛ وإلا فعرّف نوعًا مخصصًا صغيرًا مع المُنشئات القياسية، واستخدم InnerException لإضافة السياق من دون فقدان السبب.
الأسئلة الشائعة
هل درس «الاستثناءات المخصصة وتصميم الأخطاء» مجاني؟
نعم — نص درس «الاستثناءات المخصصة وتصميم الأخطاء» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 3 دروس في المجموع.
ماذا ستتعلم في «الاستثناءات المخصصة وتصميم الأخطاء»؟
أنشئ استثناءات مخصصة صغيرة، واختر الأنواع المدمجة المناسبة (ArgumentException وInvalidOperationException)، وأضف السياق باستخدام InnerException. تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟
لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 3.
كم من الوقت يستغرق درس «الاستثناءات المخصصة وتصميم الأخطاء»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟
نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- try/catch/finally وthrow new مقابل إعادة الرمي
- الاستثناءات المخصصة وتصميم الأخطاء
- IDisposable وعبارة using