Должен ли класс, который запускается только один раз, содержать статический конструктор?

Я начинаю изучать ООП-программирование на C#. Что касается дизайна, то мне имеет смысл использовать конструктор static для основного класса моей программы, учитывая, что этот класс содержит код, который запускается только один раз (вся моя программа очень проста и состоит из одного файла .cs).

Например, вот пример кода с использованием обычного конструктора:

class Program
    {
        const string file = @"C:\Program Files (x86)\myapp\log.txt";
        int status;

        static int Main(string[] args)
        {
            var myObj = new Program();
            return myObj.status;            
        }

        public Program()
        {
            int retCode;

            try {
                //  lots of procedures using the file

                retCode = 0;   // ok
            }
            catch (Exception ex) {
                Console.WriteLine(ex.Message);

                retCode = 999; // specific error
            }

            status = retCode;
        }
    }

Здесь следует та же структура, но с использованием конструктора static, так как я думаю, что это адекватно. Обратите внимание, что доступ status также был изменен.

class Program
    {
        const string file = @"C:\Program Files (x86)\myapp\log.txt";
        static int status;

        static int Main(string[] args)
        {
            return Program.status;
        }

        static Program()
        {
            int retCode;

            try {
                //  lots of procedures using the file

                retCode = 0;
            }
            catch (Exception ex) {
                Console.WriteLine(ex.Message);

                retCode = 999;
            }

            status = retCode;
        }
    }


Вопрос: Верно ли мое предположение об использовании второго кода вместо первого? Или я что-то упускаю? Другими словами: какой из них предпочтительнее (считается лучшим дизайном)? И есть ли что-то фундаментальное в статических конструкторах, что вызовет у меня проблемы в этом случае?


person first timer    schedule 29.04.2015    source источник
comment
как выглядит код вызова?   -  person Legends    schedule 29.04.2015
comment
@Legends Я думаю, это точка входа для программы здесь;)   -  person Random Dev    schedule 29.04.2015
comment
Может быть не связано напрямую, но вместо одного класса с точкой входа в программу Main и кодом используйте два отдельных класса, один с точкой входа (Program), а другой с вашей бизнес-логикой. Позже вы можете решить, будет ли этот класс статическим или нестатическим.   -  person Habib    schedule 29.04.2015
comment
Как вы думаете, что вы получаете от того, что один и тот же код находится внутри Main, а не в конструкторе?   -  person Damien_The_Unbeliever    schedule 29.04.2015
comment
Какая кукла проголосовала за это? Это законный вопрос.   -  person aevitas    schedule 29.04.2015
comment
@Damien_The_Unbeliever Я могу быть предвзятым из-за всего, что есть классы, я думаю   -  person first timer    schedule 29.04.2015
comment
Первый способ плох из-за необычного взаимодействия класса Program и функции Main. Второй способ хуже, так как он излишне полагается на автоматический вызов функции в определенный момент выполнения CLR, в отличие от фактического видимого вызова в коде, который намного понятнее, и это совершенно не нужно в этой программе.   -  person svinja    schedule 29.04.2015


Ответы (3)


Старайтесь максимально избегать использования статических конструкторов. В отличие от конструкторов экземпляров, вы не можете активно вызывать статический конструктор — он запускается при первом использовании типа (что может измениться из-за оптимизации или даже обфускации).

Также старайтесь избегать «работы» в конструкторе. Конструктор предназначен для создания экземпляра и не более того.

Поэтому в обоих случаях я бы переместил функциональность в метод. Затем этот метод может иметь фактическое возвращаемое значение, а не устанавливать свойство. Поскольку вы не поддерживаете какое-либо состояние (тогда Program.status превращается в возвращаемое значение), вы можете безопасно сделать этот метод статическим.

person C.Evenhuis    schedule 29.04.2015
comment
Спасибо, очень понятное объяснение. Вы рекомендуете мне просто поместить код в метод Main, как кто-то предлагает в комментариях? - person first timer; 29.04.2015
comment
Конечно, пока он не вырастет слишком большим. Но в любом случае я боюсь, что вы все равно будете создавать процедурную программу вместо ООП. - person C.Evenhuis; 29.04.2015

Предоставленный код делает то же самое, за исключением того, что в первом случае вы создаете объект Program вместо использования статических элементов. Это создаст дополнительные накладные расходы для вашего приложения. Теперь в этом случае действительно нет причин выбирать любой из методов, поскольку накладные расходы незначительны.

Однако в первом случае значение status основано на экземпляре. Поэтому только экземпляр Program имеет значение статуса. Следовательно, если status является полем на основе экземпляра, где несколько экземпляров Program должны поддерживать свое собственное значение поля status, вам следует использовать первый пример.

person Nico    schedule 29.04.2015

ОП, вероятно, ищет шаблон Singleton. Мое личное мнение заключается в том, что если класс будет создан только один раз, то в первую очередь очень мало причин для того, чтобы он был классом, и меньше накладных расходов на вызовы, если все методы такого класса были возвращены к статическому C. функции - но это только мое мнение.

person Homer    schedule 29.04.2015