في دلفي 7، هناك عبارة "حاول... باستثناء الرفع"؛النهاية؛` ذات معنى على الإطلاق؟

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

سؤال

في بعض أكواد دلفي 7 التي أقوم بصيانتها، لاحظت الكثير من الأمثلة التالية:

with ADOQuery1 do begin
  // .. fill out sql.text, etc
  try
    execSQL;
  except
    raise;
  end;
end;

يبدو لي أنه يمكن إزالة كتل المحاولة هذه، لأنها لا تفعل شيئًا.ومع ذلك، أنا حذر من الآثار الجانبية الخفية المحتملة.

هل يمكن لأي شخص أن يفكر في أي حالات يمكن فيها لهذه الكتل أن تفعل أي شيء لم يكن من الممكن أن يحدث بدونها؟

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

المحلول

في هذا السياق، فإن عملية رفع له أي تأثير، وينبغي إزالتها بيكوس ببساطة رفع نعيد لها استثناء أن كتلة استثناء اشتعلت فقط. رفع وعادة ما تستخدم لنقل السيطرة إلى نهاية الكتلة عندما لا معالجة الأخطاء المناسب هو متاح. في ما يلي نحن معالجة الاستثناء العرف، ولكن ينبغي التعامل مع أي استثناء في أماكن أخرى.

try
  someOperation;
except
  on e: ECustomException do
    SomeCustomHandelr;
  else
     begin
       // the raise is only useful to rethrow the exception to an encompasing 
       // handler.  In this case after I have called my logger code. as Rob
       // mentioned this can be omitted if you arent handling anything because
       // the compiler will simply jump you to the next block if there is no
       // else.
       LogUnexpectedException('some operation failed',e);
       raise;
     end;
end;

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

with ADOQuery1 do begin  
  // .. fill out sql.text, etc  
  try    
    execSQL; 
  except
    // no handler so this just eats any "errors"    
  end;

نصائح أخرى

وسوف إزالة باستثناء التعليمات البرمجية في التعليمات البرمجية المتكررة أعلاه لا فرق. يمكنك (وأعتقد أنك <م> يجب نظرا لأنه يقلل من هذين) إزالته.

حسنًا، سؤالان هنا حقًا.

أولا، ذلك يكون ذو معنى:إذا قام execSQL بطرح استثناء، فسيتم اكتشافه بواسطة كتلة المحاولة وإعادة توجيهه إلى الاستثناء.ثم تتم إعادة توجيهه عن طريق الرفع إلى الكتلة الأعلى التالية.

ثانيا هل هو مفيد؟على الاغلب لا.ويكاد يكون من المؤكد أن ذلك نتيجة لواحد من ثلاثة أشياء:

  1. كتب شخص ذو شعر مدبب معيارًا ترميزيًا ينص على أن "جميع العمليات التي يمكنها إحداث استثناء يجب أن تكون في كتلة محاولة."
  2. كان شخص ما ينوي العودة وتحويل الاستثناءات التي قدمها execSQL بيان في استثناء آخر أكثر أهمية.
  3. لم يكن أحد الأشخاص الجدد على علم بأن ما كتبوه كان متماثلًا للسماح لبيئة المستخدم بالقلق بشأن الاستثناء، ولذلك اعتقدوا أنهم يجب إحالتها.

ربما أجبت بسرعة بعض الشيء، انظر في النهاية ...
كما هو الحال، فهو عديم الفائدة للتطبيق.
فترة!

الآن على الجانب "لماذا".قد يكون ذلك لتوحيد معالجة الاستثناءات إذا كان هناك/كان/سيكون/موجودًا في أماكن أخرى/تم إدخال نوع من كود التسجيل قبل الرفع:

  try
    execSQL;
  except
    // Log Exception..
    on E: Exception do
    begin
      LogTrace(Format('%s: Exception Message[%s]',[methodname, E.Message]));
      raise;
    end;
  end;

أو للحصول على رمز التنظيف:

  try
    execSQL;
  except
    //some FreeAndNil..
    raise;
  end;

تحديث:ستكون هناك حالة واحدة حيث أرى بعض الفائدة تمامًا كما هي ...
...لتتمكن من وضع نقطة توقف على raise سطر، للحصول على فرصة لرؤية ما يحدث في سياق تلك المجموعة من التعليمات البرمجية.

وهذا الرمز لا يفعل شيئا، سوى السماح للمبرمج الأصلي لوضع نقطة توقف على 'رفع' ولرؤية استثناء أقرب في المصدر إلى سبب محتمل لها. في هذا المعنى تقنية التصحيح معقولة تماما.

في الواقع، أود أن نشر هذا النحو تعليق على إجابات فرانسوا، ولكن لا أعرف هل من الممكن لادخال كود تنسيق هناك :( لذلك أنا نشر هذا كإجابة.

و2mghie:

<اقتباس فقرة>   <اقتباس فقرة>     <اقتباس فقرة>       

والثاني هو unidiomatic تماما، واحدة ستستخدم في النهاية بدلا من ذلك.

       

ولا "، وأخيرا" سوف الكائن تنظيف دائما. "إلا" - فقط على استثناء. النظر في القضية من وظيفة، مما يخلق، يملأ وإرجاع كائن:

function CreateObj: TSomeObj;
begin
  Result := TSomeObj.Create;
  try
    ... // do something with Result: load data, fill props, etc.
  except
    FreeAndNil(Result); // oops: bad things happened. Free object to avoid leak.
    raise;
  end;
end;

إذا كنت وضعت "أخيرا" هناك - وظيفة سيعود شيء دائما. إذا قمت بحذف "محاولة" كتلة على الإطلاق - سوف تكون هناك موارد تسرب في حالة استثناء في "..."

.

وP.S. بالطبع، يمكنك استخدام "أخيرا" وتحقق ExceptObj، ولكن ... ليست قبيحة؟

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

لكن، ربما يريد Blorgbeard بالفعل معرفة ما إذا كان الأمر كذلك على الاطلاق ذات معنى ل try ... except raise; end.في دلفي 7، إذا كنت أتذكر بشكل صحيح، Exit من شأنه أن يؤدي إلى finally جزء من أ try-finally كتلة (كما لو كان نوعا من الاستثناء).قد يعتبر شخص ما أن مثل هذا السلوك غير مناسب لمهمته، واستخدام البناء المعني يعد حلاً بديلاً تمامًا.

فقط سيكون من الغريب استخدام واحدة raise; هناك، ولكن بعد ذلك كان ينبغي لنا أن تحدثنا عنه فائدة بدلا من المعنى, ، كما لاحظ تشارلي بدقة.

وهذا الرمز لا يفعل شيئا إلا رفع إعادة استثناء من شأنها أن allready قد تثار دون هذه محاولة باستثناء كتلة. يمكنك إزالته بأمان.

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