C# 将基类中的静态void Main()方法用作程序';s入口点

C# 将基类中的静态void Main()方法用作程序';s入口点,c#,console-application,entry-point,C#,Console Application,Entry Point,我想将一些程序逻辑抽象为一个基类,用于执行命令行程序(功能类似于 换句话说,类似这样的事情: public abstract class BaseProgram<T> { public static void Main(string[] args) { Console.WriteLine(typeof(T)); } } public class Program : BaseProgram<string> { } 并将输出: &g

我想将一些程序逻辑抽象为一个基类,用于执行命令行程序(功能类似于

换句话说,类似这样的事情:

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

public class Program : BaseProgram<string>
{
}
并将输出:

> System.String
> System.String

我想知道的:这种结果是否有任何书面原因?

我认为问题在于
基类
是通用的。为了调用main,您必须提供一个类型参数,那么系统应该选择哪种类型来调用此方法?当然,它不能做出随机选择,所以这是非法的

我在
3.1应用程序启动的
C#5.0语言规范中发现了这一点

应用程序入口点方法可能不在泛型类声明中


正如在对另一个答案的评论中最终披露的那样,您的
BaseProgram
类与您试图执行的类位于不同的程序集中。程序集的入口点必须位于该程序集中

否则,就像给某人一把钥匙,告诉他们那是你家前门的钥匙。除了钥匙实际上是给其他完全不同的房子的前门的,所以当他们出现在你家时,对他们没有好处

如果要使用
BaseProgram
Main()
方法,则需要委托给它。例如,在您自己的程序集中:

static class Program
{
    public static int Main(string[] args)
    {
        return BaseProgram<string>.Main(args);
    }
}
静态类程序
{
公共静态int Main(字符串[]args)
{
返回BaseProgram.Main(args);
}
}

请注意,对于静态类型或类型的静态成员,实际上不需要继承基类型,因为您只需通过实际的类型名而不是实例引用来调用它。

我可以想象,因为它无法实例化隐式启动对象。您是否尝试显式设置启动对象?使用Program.Main()作为入口点,并在那里实例化您自己的类树。是的,@abatishchev,这就是我所做的,以实现我所追求的功能,但我想知道它只是没有在基类中使用
Main
方法是否有原因。@BradleyDotNET否,我没有。但是,它不允许我将基类设置为启动对象。只有“程序”类可用。可能是因为它在另一个项目中?显式设置为
Program
可能会起作用。我刚刚从基类中删除了泛型参数,它仍然无法编译(我也无法将其设置为“启动对象”)。这肯定是有道理的,但…该规范完全支持你的答案。然而,我仍然相信这是一个不同的问题。当我将
Program
设置为泛型和
BaseProgram
非泛型(la
Program:BaseProgram
)时,我收到一个不同的编译器错误:为Main方法指定的错误14“Program”必须是有效的类或结构程序。当然,这可能是原因。如果项目类型不是类库,则每个项目都应该有一个单独的main方法。你为什么不说你有两个独立的项目?@skeryl:当然这就是原因。程序集的入口点必须位于该程序集中!如果你提到了这种情况,你的问题在19分钟前就会得到正确的回答。@skeryl:它不会“删除任何抽象的用途”。这意味着您需要在程序集中定义一个有效的入口点。您始终可以将实际功能委托给另一个程序集,包括通过继承然后调用的泛型基类。
static class Program
{
    public static int Main(string[] args)
    {
        return BaseProgram<string>.Main(args);
    }
}