Подтвердить что ты не робот

Исключение в статическом конструкторе

Я выкопал SO для ответа на этот вопрос, и самый лучший, который я могу найти до сих пор, здесь, однако он ориентирован на экземпляры со статическими конструкторами; Я использую класс статически.

Мой код:

public static class MailHelper {

    private static string mailHost;

    static MailHelper() {

        var mailSettings = ConfigurationManager.GetSection("MailSettings") as NameValueCollection;
        if (null == mailSettings) {
            throw new ConfigurationErrorsException("Missing Mail Settings in the configuration file");
        }

        mailHost = ConfigurationManager.AppSettings["mailHost"];
        if (null == mailHost) {
            throw new ConfigurationErrorsException("Missing mailHost setting in the configuration file");
        }

    }

    public static void SendMail(MailMessage Message) {
        ...
    }

}


try {
    MailHelper.SendMail(Message);
}
catch (ConfigurationErrorsException exc) {
    ...
}

//  ???    
MailHelper.SendMail(Message);


.

Итак, если статический конструктор выдает исключение при первом вызове, что происходит во второй раз, я пытаюсь получить доступ к статическому методу SendMail()?

PS: Извините, если вам не нравится Stroustrup версия стиля K & R brace, но не редактируйте мой пост, чтобы просто изменить фигурные скобки в ваш предпочтительный стиль Allman. Спасибо.

4b9b3361

Ответ 1

Два других ответа - это хорошие ответы на ваш прямой вопрос - здесь метаанализ - вы должны бросать исключение в метод, когда обнаруживаете, что элементы конфигурации не заполнены, а не в конструкторе. IMHO, "не настроено", является допустимым состоянием конфигурации для этих элементов на фазе конструктора, просто не во время отправки. Это обойдется всей этой проблемой.

Ответ 2

Как только инициализатор типа завершился с ошибкой один раз, он никогда не будет повторен. Тип мертв для жизни AppDomain. (Обратите внимание, что это верно для всех инициализаторов типов, а не только для типов со статическими конструкторами. Тип со статическими переменными с выражениями инициализатора, но без статических конструкторов, может проявлять незначительные различия в времени выполнения инициализатора типа, но это будет еще только один раз.)

Демонстрация:

using System;

public sealed class Bang
{
    static Bang()
    {
        Console.WriteLine("In static constructor");
        throw new Exception("Bang!");
    }

    public static void Foo() {}
}

class Test
{
    static void Main()
    {
        for (int i = 0; i < 5; i++)
        {
            try
            {
                Bang.Foo();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.GetType().Name);
            }
        }
    }
}

Вывод:

In static constructor
TypeInitializationException
TypeInitializationException
TypeInitializationException
TypeInitializationException
TypeInitializationException

Как вы можете видеть, статический конструктор вызывается только один раз.