هل من السيئ استخدام حاول متداخلة..التقاط كتل مثل هذا؟

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

  •  05-07-2019
  •  | 
  •  

سؤال

هل هذه فكرة سيئة؟هل هناك طريقة أفضل لتحقيق نفس التأثير؟

// assume that "name" is a string passed as a parameter to this code block
try
{
    MainsDataContext dx = new MainsDataContext();
    try
    {
        Main m = dx.Main.Single(s => s.Name == name);
        return m.ID;
    }
    catch (InvalidOperationException)
    {
        Guid g = Guid.NewGuid();

        Main s = new Main 
        {
            Name = name,
            ID = g
        };

        dx.Mains.InsertOnSubmit(s);
        dx.SubmitChanges();

        return g;
    }
}
catch (Exception ex)
{
    // handle this
}

الهدف هنا هو الحصول على معرف السجل إذا كان موجودًا، وإلا قم بإنشاء هذا السجل وإرجاع المعرف الخاص به.

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

المحلول

يجب عليك استخدام SingleOrDefault، وبهذه الطريقة إذا لم يكن السجل موجودًا، فسوف يُرجع القيمة الافتراضية للفئة الخالية.

MainsDataContext dx = null;    
try
    {
         dx = new MainsDataContext();

        Main m = dx.Main.SingleOrDefault(s => s.Name == name);

        if ( m == null)
        { 
           Guid g = Guid.NewGuid();

           m = new Main 
          {
              Name = name,
              ID = g
          };

         dx.Mains.InsertOnSubmit(m);
         dx.SubmitChanges();

        }

        return m.ID;
    }
    catch (Exception ex)
    {
        // handle this
    }
    finally
    {
       if(dx != null)
          dx.Dispose();
    }

إنها فكرة جيدة لاستخدام استخدام الكلمة الأساسية عند استخدام DataContext

using ( MainsDataContext dx = new MainsDataContext())
{
        Main m = dx.Main.SingleOrDefault(s => s.Name == name);

        if ( m == null)
        { 
           Guid g = Guid.NewGuid();

           m = new Main 
          {
              Name = name,
              ID = g
          };

         dx.Mains.InsertOnSubmit(m);
         dx.SubmitChanges();

        }

        return m.ID;
}

نصائح أخرى

Main m = dx.Main.SingleOrDefault(s => s.Name == name);

if (m == default(Main))
{
    // it does not exist
}
else
{
    // it does exist
}

<الإضراب> ليس من الواضح من السؤال إذا كان نوع Main هي فئة أو بنية (تحرير: أنا فقط أدركت أن في الواقع يجب أن يكون فئة)، وبالتالي اعتدت default() بدلا من مجرد مقارنة لnull.

وسؤالي سيكون الشفرة التي تنوي وضعها في هنا:

// handle this

ومع كتلة التقاط الأول، وتعلمون أن واحدة () رمى InvalidOperationException لأن تسلسل يحتوي على أكثر من عنصر واحد أو فارغ.

في الثانية، يمكن أن تحصل على كل أنواع الأخطاء. مرجع فارغة، والوصول إلى البيانات، الخ كيف أنت ذاهب للتعامل مع هذه؟

وقبض فقط ما كنت تعرف كيفية التعامل معها، وتكون محددة في نوع باستثناء ما تستطيع.

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

لا، ولكن قد ترغب في refector كتلة الداخلي إلى أسلوب خارجي.

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