كيفية استخدام الكلمة الرئيسية رميات على غرار Java في C#؟

StackOverflow https://stackoverflow.com/questions/3465465

سؤال

في جافا ، throws تتيح الكلمة الرئيسية طريقة لإعلان أنها لن تتعامل مع استثناء من تلقاء نفسها ، ولكن رميها على طريقة الاتصال.

هل هناك كلمة رئيسية مماثلة/سمة في C#؟

إذا لم يكن هناك ما يعادل ، فكيف يمكنك إنجاز نفس التأثير (أو مماثل)؟

هل كانت مفيدة؟

المحلول

في Java ، يجب عليك إما التعامل مع استثناء أو وضع علامة على الطريقة التي قد ترميها باستخدام throws الكلمة الرئيسية.

لا يحتوي C# على هذه الكلمة الرئيسية أو الكلمة المكافئة ، كما هو الحال في C# ، إذا لم تتعامل مع استثناء ، فسيتم تفويتها ، حتى يتم القبض عليها أو إذا لم يتم القبض عليها ، فسيقوم بإنهاء البرنامج.

إذا كنت ترغب في التعامل معها ، فاحرص على ذلك ، يمكنك القيام بما يلي:

try
{
  // code that throws an exception
}
catch(ArgumentNullException ex)
{
  // code that handles the exception
  throw;
}

نصائح أخرى

OP يسأل عن ج# ما يعادل جافا throws بند - ليس throw الكلمة الرئيسية. يتم استخدام هذا في توقيعات الطريقة في Java للإشارة إلى استثناء محدد يمكن إلقاؤه.

في C#، لا يوجد ما يعادلها المباشر لاستثناء Java الذي تم فحصه. C# ليس له جملة توقيع طريقة مكافئة.

// Java - need to have throws clause if IOException not handled
public void readFile() throws java.io.IOException {
  ...not explicitly handling java.io.IOException...
}

يترجم إلى

// C# - no equivalent of throws clause exceptions are unchecked
public void ReadFile() 
{
  ...not explicitly handling System.IO.IOException...
}

نعم ، هذا موضوع قديم ، لكنني أجد في كثير من الأحيان خيوط قديمة عندما أقوم بإجابات googling ، لذا اعتقدت أنني سأضيف شيئًا مفيدًا وجدته.

إذا كنت تستخدم Visual Studio 2012 ، فهناك أداة مدمجة يمكن استخدامها للسماح بمستوى "رميات" IDE.

كما ترى تعليقات الوثائق XML, ، كما ذكر أعلاه ، ثم يمكنك استخدام u003Cexception> علامة لتحديد نوع الاستثناء الذي ألقاه الطريقة أو الفئة وكذلك المعلومات حول متى أو لماذا يتم إلقاؤه.

مثال:

    /// <summary>This method throws an exception.</summary>
    /// <param name="myPath">A path to a directory that will be zipped.</param>
    /// <exception cref="IOException">This exception is thrown if the archive already exists</exception>
    public void FooThrowsAnException (string myPath)
    {
        // This will throw an IO exception
        ZipFile.CreateFromDirectory(myPath);
    }

إليك إجابة على سؤال مماثل قمت بتمويله للتو bytes.com:

الجواب المختصر هو لا ، لا توجد استثناءات محددة في C#. يناقش مصمم اللغة هذا القرار في هذه المقابلة:

http://www.artima.com/intv/handcuffs.html

الأقرب الذي يمكنك الحصول عليه هو استخدام العلامات في وثائق XML الخاصة بك ، وتوزيع مستندات NDOC التي تم إنشاؤها مع الكود/التجميعات الخاصة بك حتى يتمكن الآخرون من معرفة الاستثناءات التي ترميها (وهو ما تفعله MS بالضبط في وثائق MSDN). لا يمكنك الاعتماد على المترجم لإخبارك عن الاستثناءات غير المعروفة ، ومع ذلك ، كما قد تستخدم في Java.

بعد مرور معظم الإجابات هنا ، أود إضافة بعض الأفكار.

  1. الاعتماد على تعليقات وثائق XML وتوقع الاعتماد على الآخرين هو خيار ضعيف. لا يقوم معظم التعليمات البرمجية C# التي واجهتها بتوثيق أساليب تمامًا ومتسقة مع تعليقات وثائق XML. ثم هناك مشكلة أكبر دون استثناءات محددة في C#، كيف يمكنك توثيق جميع الاستثناءات التي ترميها طريقتك لغرض مستخدم API الخاص بك لمعرفة كيفية التعامل معها جميعًا بشكل فردي؟ تذكر ، أنت تعرف فقط عن تلك التي ترميها بنفسك الكلمة الرئيسية في التنفيذ. واجهات برمجة التطبيقات التي تستخدمها داخل تنفيذ الطريقة قد ترمي أيضًا استثناءات لا تعرفها لأنها قد لا يتم توثيقها ولا تتعامل معها في تنفيذك ، لذلك سوف تنفجر في مواجهة المتصل الخاص بك طريقة. وبعبارة أخرى ، فإن تعليقات توثيق XML هذه ليست بديلة للاستثناءات المحددة.

  2. ربط أندرياس مقابلة مع Anders Hejlsberg في الإجابات هنا حول سبب قرار فريق التصميم C# ضد الاستثناءات المحددة. يتم إخفاء الرد النهائي على السؤال الأصلي في تلك المقابلة:

يحمي المبرمجون رمزهم عن طريق الكتابة Try's's's's في كل مكان ، لذلك سوف يتراجعون بشكل صحيح في حالة حدوث استثناء ، لكنهم لا يهتمون فعليًا بالتعامل مع الاستثناءات.

بمعنى آخر ، لا ينبغي لأحد أن يهتم بنوع الاستثناء الذي يمكن توقعه في واجهة برمجة تطبيقات معينة لأنك ستقوم دائمًا بالقبض عليها جميعًا في كل مكان. وإذا كنت ترغب في الاهتمام حقًا باستثناءات معينة ، فإن كيفية التعامل معها متروك لك وليس شخصًا يحدد توقيع الطريقة بشيء مثل الكلمة الرئيسية Java ، مما يفرض استثناءات خاصة على مستخدم API.

--

شخصيا ، أنا ممزقة هنا. وأنا أتفق مع أندرس على أن استثناءات التحقق من عدم حل المشكلة دون إضافة مشاكل جديدة ومختلفة. تمامًا كما هو الحال مع تعليقات وثائق XML ، نادراً ما أرى رمز C# مع كل شيء ملفوف في Tryly Blocks. إنه شعور بالنسبة لي على الرغم من أن هذا هو الخيار الوحيد الخاص بك بالفعل وشيء يبدو وكأنه ممارسة جيدة.

في الواقع ، لا يمكن اعتبار عدم وجود استثناءات في C# شيئًا جيدًا أو سيئًا.

أنا نفسي أعتبر أنه حل جيد لأن الاستثناءات التي تم فحصها توفر لك المشكلات التالية:

  1. استثناءات تقنية تتسرب إلى طبقة الأعمال/المجال لأنه لا يمكنك التعامل معها بشكل صحيح على المستوى المنخفض.
  2. إنهم ينتمون إلى توقيع الأسلوب الذي لا يلعب دائمًا مع تصميم API.

بسبب ذلك في معظم التطبيقات الأكبر سترى النمط التالي في كثير من الأحيان عند حدوث استثناءات محددة:

try {
    // Some Code
} catch(SomeException ex){
    throw new RuntimeException(ex);
}

وهو ما يعني بشكل أساسي محاكاة الطريقة التي يتعامل بها C#/.

أنت تسأل عن هذا:

إعادة تربية استثناء

public void Method()
{
  try
  {
      int x = 0;
      int sum = 100/x;
  }
  catch(DivideByZeroException e)
  {
      throw;
  }
}

أو

static void Main() 
    {
        string s = null;

        if (s == null) 
        {
            throw new ArgumentNullException();
        }

        Console.Write("The string s is null"); // not executed
    }

هناك بعض أوجه التشابه العابرة بين Codecontract EnsuresOnThrow<> وجافا throws واصف ، حيث يمكن أن يشير كلاهما إلى المتصل كنوع من الاستثناءات التي يمكن رفعها من وظيفة أو طريقة ، على الرغم من وجود اختلافات كبيرة بين 2:

  • EnsuresOnThrow<> يتجاوز مجرد ذكر الاستثناءات التي يمكن إلقاؤها ، ولكنها تنص أيضًا على الظروف التي يتم بموجبها ضمان إلقاؤها - يمكن أن يكون هذا رمزًا شاقًا تمامًا في الطريقة المدعومة إذا لم تكن حالة الاستثناء تافهة لتحديدها. جافا throws يوفر مؤشرا على الاستثناءات التي يمكن إلقاؤها (أي IMO التركيز في .NET موجود داخل الطريقة التي تعاقد لإثبات throw, ، بينما في جافا ، ينتقل التركيز إلى المتصل للاعتراف بإمكانية الاستثناء).
  • .NET CC لا يميز بين فحص مقابل دون رادع الاستثناءات التي لدى Java ، على الرغم من أن القسم الدليل CC 2.2.2 يذكر

"استخدم شروط ما بعد الاستثمار فقط لتلك الاستثناءات التي يجب أن يتوقعها المتصل كجزء من واجهة برمجة التطبيقات"

  • في .NET ، يمكن للمتصل تحديد ما إذا كان يجب القيام بأي شيء باستثناء (على سبيل المثال عن طريق تعطيل العقود). في جافا ، المتصل يجب أن تفعل شيئا, ، حتى لو أضاف أ throws لنفس الاستثناء على الواجهة.

دليل عقود رمز هنا

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top