【问题标题】:Why should the Main() method be static?为什么 Main() 方法应该是静态的?
【发布时间】:2021-02-06 20:13:29
【问题描述】:

我尝试在 C# 中创建public void Main();它说 没有找到静态 void Main
Main 是静态的究竟意味着什么?我知道代码对public static void Main() 工作正常。

但是为什么Main 必须是static

【问题讨论】:

  • 有人问过关于 java 的类似问题,我认为答案也适用于这里:stackoverflow.com/questions/146576/…
  • 不清楚你问是因为你不明白static 的意思一般 还是这具体是Main

标签: c#


【解决方案1】:

您需要一个进入程序的入口点。静态意味着您可以调用函数而不必实例化类的对象/实例。这有点“鸡和蛋”……你不能在进入程序之前实例化一个对象。

可以在不实例化对象的情况下调用静态方法。因此,main() 必须是静态的,才能让它成为您程序的入口。

正如 David 所说,您只需将关键字 static 添加到函数定义中即可对其进行更改。值得研究一下静态(类)方法与实例方法,了解其中的区别有时会很有用。

【讨论】:

  • “在你进入程序之前你不能实例化一个对象。”这显然是错误的。在执行Main 之前,运行时会实例化大量对象。您可以通过将静态构造函数放入包含Main 的类中来自己触发它。抱歉,我知道这个帖子已经超过 1 年了,但我觉得这是相关的。
  • 关键点是:语言被定义为不实例化一个对象,然后在它上面调用Main。它被定义为调用静态函数。它可能会以不同的方式工作,但不会。
【解决方案2】:

只有静态 main 方法可以完成这项工作,因为有一个定义这种行为的约定。没有其他原因。

看看C# language specification

应用程序启动发生在执行环境调用一个 指定方法,称为应用程序的入口 点。这个入口点方法总是命名为Main,并且应该有 以下签名之一:

     static void Main() {…}  
     static void Main(string[] args) {…}  
     static int Main() {…}  
     static int Main(string[] args) {…}

如图所示,入口点可以选择 返回一个int 值。该返回值在应用程序中使用 终止(§10.2)。

注意:以上引用自4th edition,现在标记为“历史”。当前版本的措辞不同。

除此之外,名称Main 可以更改为其他名称。在这种情况下,必须添加一个编译器选项,告诉 C# 编译器将不同的方法标记为程序的入口点。

【讨论】:

  • 您的回答很好地解释了什么是静态方法。您还解释了 main 方法是程序的入口点。但是提问者已经知道了。他想知道的是为什么他必须使用静态方法。我的回答说没有根本的宇宙原因。语言设计者选择了这种方式。可能是受到了 C、C++ 和 Java 等其他语言的影响。
  • 我看你没听懂我说的话!这是关于设计决策。算了
  • @ThomasClayson 语言设计者本可以很好地决定创建一个 Program 实例并在其上调用 Main。我认为这两个答案都是正确的,这是一个设计决定,因为他们考虑了您在回答中所说的内容,恕我直言
  • 这是(唯一!)正确答案。其他人都错了,原因突出显示in a more detailed discussion on Programmers.SE /cc @ThomasClayson。
【解决方案3】:

类中有两种方法:

  1. 非静态方法
  2. 静态方法

// Example of static and non-static methods and how to call
namespace TestStaticVoidMain
{
    class Program
    {
        Static Void Main(string[] args)
        {
           // Instantiate or create object of the non-static method:
            Exam ob = new Exam();
            // Call the instance:
            ob.Test1();

            // Directly the call the static method by its class:
            Exam.Test2();

            Console.ReadKey();
        }
    }
    class Exam
    {
        public void Test1()
        {
            Console.WriteLine("This is a non-static method");
        }

        public static void Test2()
        {
            Console.WriteLine("This is a static method");
        }
    }
}

1.静态方法:

要调用静态方法(函数),我们不需要实例化或创建该方法的对象。我们不能使用new关键字,因为在加载和编译类时,static关键字默认会实例化或创建该类方法的对象,所以我们直接调用静态方法。

关于static void Main(string[] args),我们已经讨论过static。其余为void Main(string[] args)void 是一种不返回任何内容的数据类型。 Main() 是执行 C# 程序的标准入口点。可选参数string[] args 接收程序运行时使用的可选“命令行”参数。

2。非静态方法:

要调用非静态方法,我们必须实例化或创建类方法的对象,以使用关键字new调用类的方法(函数)。

如果名为Test 的类有一个名为show()非静态方法,那么它将如何调用实例:

// to call non-static method
Test ob=new Test();
ob.show();

【讨论】:

    【解决方案4】:

    从概念上讲,框架可以指定不是使用特定的静态方法来运行程序,而是构造某个特定类的默认实例并在其上运行某些特定方法。如果一个框架通过让它们成为编译器初始化的单例实例的实例成员来实现静态方法,那么这种方法可能是完全合理的,因为无论如何框架都必须在调用主函数之前生成一个新的对象实例.

    如果调用静态方法比构造新对象实例并调用其上的方法“更容易”,那么要求框架使用更昂贵的操作过程并没有太大的好处。任何想要使用后一种方法的代码都可以完全免费使用:

    public static void Main( [[params]] )
    {
      var mainObject = new MainObject();
      mainObject.Main( [[params]] );
    }
    

    让系统包含自己的静态方法可能会带来一些潜在的好处,如下所示:

    public static void SysMain( [[params]] )
    {
      using (Application app = new UserApp( [[params]] )) // UserApp derives from Application
      {
        app.Start(); // Virtual method
        app.AllowNext(); // Base method--see text
        app.Run(); // Abstract method
      }
    }
    

    其中app.AllowNext() 是一种与基本上同时启动的其他应用程序实例进行协调的方法,以确保重复尝试在后台启动应用程序将严格按顺序处理其Start 调用。然而,如果没有这样的协调方案,要求框架在运行之前构造一个应用程序对象并没有太大的好处。成本不会很大,但如果没有任何潜在的可识别收益,即使是微不足道的成本也没有多大意义。

    【讨论】:

      【解决方案5】:

      在应用程序启动期间,当没有创建类的对象时,必须调用 Main 方法才能开始执行程序。 Main 有时被称为应用程序的入口点。将 Main 声明为静态允许执行环境调用 Main 而无需创建类的实例。方法 Main 通常使用标头声明:

      static void Main(){..}
      

      但也可以用header声明:

      static void Main(string[] args){..}
      

      您可以使用返回类型 int(而不是 void)声明 Main — 如果一个应用程序由另一个应用程序执行并且需要向另一个应用程序返回成功或失败的指示,这将非常有用。

      【讨论】:

        【解决方案6】:

        main 应该是静态的,它首先加载并成为程序的入口点,因此 main 必须是静态的。

        【讨论】:

          猜你喜欢
          • 2012-12-28
          • 1970-01-01
          • 2015-10-15
          • 2014-11-02
          • 2018-10-27
          • 2011-03-12
          • 2016-05-30
          • 1970-01-01
          • 2012-09-15
          相关资源
          最近更新 更多