2014-11-20 3 views
1

Я хотел бы абстрагировать некоторую программную логику базовому классу для выполнения командной строки (функциональность похожа на то, что this question was requesting).Использование метода static void Main() из базового класса в качестве точки входа программы

другими словами, что-то вроде этого:

public abstract class BaseProgram<T> 
{ 
    public static void Main(string[] args) 
    { 
     Console.WriteLine(typeof(T)); 
    } 
} 

public class Program : BaseProgram<string> 
{ 
} 

Важно отметить, что BaseProgram находится в другой сборке.

Это, впрочем, не работает. Метод static void Main(string[] args)должен быть в производном классе. Может ли кто-нибудь объяснить, почему это так? В конце концов, следующее полностью «легальный»:

Program.Main(null); 
BaseProgram<string>.Main(null); 

и выход:

> System.String 
> System.String 

То, что я хотел бы знать: есть ли какие-либо документированные причины такого результата?

+1

Я бы предположил, потому что он не может создать экземпляр неявного объекта запуска. Вы пытались * явно * установить объект запуска? – BradleyDotNET

+0

Используйте Program.Main() для точки входа и создайте свое собственное дерево классов. – abatishchev

+0

Да, @abatishchev, это то, что я делаю, чтобы достичь той функциональности, которой я был, но я хотел знать, была ли причина, по которой он просто не использовал метод Main в базовом классе. – skeryl

ответ

3

В конце концов, было раскрыт во время комментирования другого ответа, ваш BaseProgram<T> класса находится в другой сборке от одного вы пытаетесь выполнить. Точка входа сборки должна быть в , что сборка.

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

Если вы хотите использовать метод, то вам необходимо делегировать его. Например, в своей собственной сборке:

static class Program 
{ 
    public static int Main(string[] args) 
    { 
     return BaseProgram<string>.Main(args); 
    } 
} 

Обратите внимание, что для статических типов или статических членов типов, нет никакой необходимости фактически наследуют базовый тип, так как вы просто вызвать его с помощью фактического имени типа вместо экземпляра Справка.

+0

Не очевидно, как вы знали, что BaseProg находится в другой сборке. Если кто-то запутался, @skeryl, который задал вопрос, разместил эту информацию в одном из комментариев. –

+1

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

+0

Кроме того, для некоторых функций «реального» класса BaseProgram необходимо, чтобы класс 'Program' наследовал класс' BaseProgram'. Вот что изначально заставило меня любоваться этой проблемой: я заметил, что я могу вызвать метод BaseProgram .Main() 'через' Program.Main() ' – skeryl

4

Я думаю, проблема в том, что BaseClass является общим. Чтобы вызвать main, вам нужно указать аргумент типа, и какой тип должен выбрать система для вызова этого метода? Конечно, он не может делать случайные выборы, поэтому это незаконно.

Я нашел это в C# 5.0 Language Specification в 3.1 Application Startup

The application entry point method may not be in a generic class declaration.

+0

Я просто удалил параметр Generic из базового класса, и он все равно не будет компилироваться (и я также не могу установить его как «объект запуска»). Это будет * определенно * иметь смысл, хотя ... – skeryl

+1

@skeryl вы уверены? меня устраивает. –

+0

Эта спецификация. полностью поддерживает ваш ответ. Тем не менее, я по-прежнему убежден, что это другая проблема. Когда я делаю 'Program' родовыми и' BaseProgram' не родовыми (а-ля 'Программа : BaseProgram') Я получаю другую ошибку компиляции: Ошибка \t \t 14«Программы », указанную для главного метода должен быть допустимым классом или struct Program.cs – skeryl