Создание экземпляра класса, содержащего static void Main()

Я просматриваю консольное приложение C# коллеги и вижу этот фрагмент:

class Program
{
    static void Main(string[] args)
    {
        Program p = new Program();
        p.RealMain();
    }

    ... non-static RealMain function
}

Предположительно, он делает это, потому что хочет иметь поля уровня экземпляра и т. д.

Я такого раньше не видел, но этот стиль меня бесит. Является ли это общепринятой и общепринятой практикой?


person anonymous    schedule 12.05.2011    source источник
comment
Что не так с этим? Что вы имеете против переменных экземпляра? Вы никогда не используете их?   -  person David Heffernan    schedule 12.05.2011
comment
Мне это кажется странным, но я не могу авторитетно сказать вам, обычно это или хорошо.   -  person ThatMatthew    schedule 12.05.2011
comment
@David Heffernan - у меня нет веских аргументов за или против этого (как и у @ThatMatthew). Просто статические поля так же просты в использовании, и вам не нужно создавать экземпляр внешнего класса.   -  person anonymous    schedule 12.05.2011
comment
@David Heffernan У него вообще нет проблем с переменными экземпляра. У него проблема с созданием экземпляра класса, который обычно используется только для вызова статического метода.   -  person ThatMatthew    schedule 12.05.2011


Ответы (8)


Существует мнение, что функция main() объектно-ориентированного кода должна делать как можно меньше. Main() — это «уродливый» возврат к процедурному дизайну кода, когда программы писались в одной функции, вызывая подпрограммы только по мере необходимости. В ООП весь код должен быть инкапсулирован в объекты, которые выполняют свою работу, когда им говорят.

Таким образом, вы уменьшаете LOC в точке входа main() до двух строк, а реальная логика программы структурируется и выполняется в более простой форме.

person KeithS    schedule 12.05.2011
comment
Итак, когда вы сами пишете консольные приложения, вы этим занимаетесь? - person anonymous; 12.05.2011
comment
Нет. Я не говорил, что подписался на эту школу мысли :) - person KeithS; 12.05.2011

Это имеет смысл для меня.

В частности, вы можете добавить в Main только логику, достаточную для разбора аргументов командной строки (возможно, с использованием обобщенного анализатора аргументов), а затем передать эти параметры в конструктор строго типизированным способом, подходящим для рассматриваемая программа.

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

person Jon Skeet    schedule 12.05.2011
comment
Итак, когда вы сами пишете консольные приложения, вы этим занимаетесь? - person anonymous; 12.05.2011
comment
@anonymous: Иногда да. Все зависит от ситуации, но я определенно думаю, что это имеет смысл, особенно если тестирование будет чище. Чем меньше проект, тем больше в нем смысла - если ваш проект содержит только пару классов, наличие дополнительного для Main не является ненужным беспорядком IMO. - person Jon Skeet; 12.05.2011

Никогда не видел его раньше. Если вы хотите использовать этот шаблон, создайте отдельный Program2-класс с RealMain и создайте его экземпляр.

Зачем нужны поля уровня экземпляра? Статических полей недостаточно?

Может быть преимущество, если вы хотите создать множество экземпляров Program классов.

Я не вижу ничего особенно плохого в этом подходе, просто я не видел его раньше.

person Albin Sunnanbo    schedule 12.05.2011
comment
Зачем нужны поля уровня экземпляра? Статических полей недостаточно? -- Хороший вопрос. Думаю, мне придется спросить разработчика, но мне сложно представить ситуацию, в которой потребовалось бы несколько экземпляров Program со своими собственными нестатическими полями. Это просто консольное приложение. - person anonymous; 12.05.2011

если вы хотите получить non static functions, вам нужно сделать так.

class Program
{
    static void Main(string[] args)
    {
        Program p = new Program(); // dependency of the class will be there.So not a good practice
        p.RealMain();// if you want initalize, you have to go like this or better you can do it in some other class.
    }

    void RealMain(){} 
}
person anishMarokey    schedule 12.05.2011

Точка входа приложения всегда определяется как static void Main(...).
Вы можете написать свой код внутри Main() или использовать этот метод для запуска чего-то еще, расположенного в другом месте... решать вам...

person Marco    schedule 12.05.2011

Общепринятой практикой является создание экземпляра отдельного класса, который может содержать все, что вам нужно. Приведенный выше фрагмент выглядит как минимум странно :).

person Centro    schedule 12.05.2011
comment
Кем именно принято? Любые ссылки? - person Jon Skeet; 12.05.2011
comment
@Jon Skeet Под принятым я имел в виду, что эта практика используется почти везде, метод Main обычно служит точкой входа в само приложение, например, в приложениях Windows, где сначала создается экземпляр формы, а затем метод реальной точки входа - Show - называется. - person Centro; 12.05.2011
comment
@Centro: это действительно зависит от того, что вы делаете. Для небольших инструментов у меня обычно будет только один класс — независимо от того, создан он или нет. Я не думаю, что есть какая-то польза от наличия двух классов, а не одного, просто чтобы не иметь Main в одном классе. - person Jon Skeet; 12.05.2011
comment
@Jon Skeet Возможно, для небольших приложений это имеет смысл, но для реальных приложений метод Main должен быть максимально понятным. - person Centro; 12.05.2011
comment
@Centro: Что заставляет вас думать, что приложения реального мира не могут быть маленькими? Я написал множество небольших инструментов, которые очень часто используются в реальном мире. Конечно, большая часть приложений вообще не имеет метода Main — это веб-приложения, веб-службы или что-то еще. - person Jon Skeet; 12.05.2011
comment
@Jon Skeet Когда приложение выполняет реальную работу, у него должны быть классы со своими обязанностями за выполнение этой работы. Ответственность класса Program заключается только в том, чтобы инициировать другие обязанности. Конечно, для простых приложений это не имеет значения, и вся логика может быть только в методе Main. - person Centro; 12.05.2011
comment
@Centro: это мало что дает для тестируемости, не так ли? Область инструментов, которые охватывают только несколько классов, но где вы хотите иметь возможность их тестировать (и, следовательно, хотите, чтобы экземпляры, а не статические методы, сохраняли состояние отдельно между тестами), довольно широка IMO. - person Jon Skeet; 12.05.2011
comment
@Jon Skeet Конечно, лучше использовать экземпляры для тестирования, а не статические методы, если вы это имели в виду. - person Centro; 12.05.2011
comment
@Центро: Да. Вместо того, чтобы использовать кучу статических методов в одном классе, используйте кучу методов экземпляра в одном классе и заставьте Main просто создать экземпляр этого класса (передав любую подходящую конфигурацию и т. д.). Теперь этот класс может быть отдельным, но на самом деле я не вижу особой пользы от помещения Main в отдельный класс, если единственная его цель - создать другой экземпляр и сказать "давай". - person Jon Skeet; 12.05.2011

Если бы это был какой-то другой класс, кроме «Программы», вопроса бы не возникло. Этот дизайн дает вам возможность создавать несколько экземпляров «Программы», возможно, в будущем, так почему бы и нет. Я с KeithS здесь: как можно меньше в статической пустоте Main.

person Oli    schedule 12.05.2011

Я часто вижу это, особенно для быстрых консольных программ, созданных, чтобы попробовать что-то или протестировать что-то.

Visual Studio практически поощряет это — если вы запросите новую консольную программу, она создаст один файл с классом, содержащим только метод Main.

Если вы не делаете что-то сложное, для чего требуется более 1 класса, или что-то очень простое, для чего вообще не требуется класс (т.е. все методы и переменные статичны), почему бы вам не сделать это таким образом?

person Nikki Locke    schedule 12.05.2011