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

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

мой код:

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: Извините, если вам не нравится версия K&R Страуструпа brace styling, но не редактируйте мой пост, чтобы изменить фигурные скобки на ваш предпочтительный стиль Allman. Спасибо.

3 ответов


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


после того, как инициализатор типа потерпел неудачу один раз, он никогда не повторяется. Тип мертв для жизни 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

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