1

I just started learning C# (on Xamarin) and I'm confused about something, coming from a PHP background.

I used a fresh console project template and there is a class in Program.cs

using System;

namespace Test
{
    class MainClass
    {
    public static void Main(string[] args)
    {
    Console.WriteLine("Hello World!");
    }
    }
}

This writes Hello World! to the console as expected. But the class MainClass has never been initialized. Why is it executed?

Edit

Changing my question: Who executed the constructor?

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
Semicolon
  • 1,904
  • 14
  • 26

7 Answers7

4

The Main Method is static, which allows a call without instance.

Mike Miller
  • 16,195
  • 1
  • 20
  • 27
  • That makes sense, but who called it? – Semicolon Sep 01 '16 at 11:41
  • See related http://stackoverflow.com/questions/11332494/why-should-main-be-static – rbm Sep 01 '16 at 11:42
  • 1
    The debugger probably in your instance, Main is described as the entry point to a default console project. It's a bit like clicking your Word icon, that will probably call a Static main method that then creates whatever it needs. – Mike Miller Sep 01 '16 at 11:42
  • So you could say it's in the nature of a console project, that the static classes in Program.cs are automatically called? – Semicolon Sep 01 '16 at 11:45
  • No it's a property that can be define against a project. You can have a Main method in any class and define that as the startup. – Mike Miller Sep 01 '16 at 11:48
  • 2
    @Faloude - the `Program` class is a *convention* (based on the default C# templates), not a *requirement*. You can have a `Main` in any class you like, provided it follows the [correct requirements](https://msdn.microsoft.com/en-us/library/acy3edy3.aspx) – Damien_The_Unbeliever Sep 01 '16 at 11:51
3

Main is the entry point of the program. The operating system calls the Main method for you when you run the program. Because Main is a static method, it does not need to create an instance of MainClass to do so.

To be a valid entry point, the Main method must be static and have return type void or int, and either no parameters or a single string[] parameter. (See: https://msdn.microsoft.com/en-us/library/acy3edy3.aspx)

If you have multiple Main methods in your program that are valid entry points, you choose which one to use with compiler settings.

Joren
  • 14,472
  • 3
  • 50
  • 54
  • This answers my exact question. By `Main` being the entry point of the program, you mean `MainClass` right? – Semicolon Sep 01 '16 at 11:53
  • But if I would be to write another class in the same file, also containing a `Main` method, which class `Main` method would be the entry point of the program? – Semicolon Sep 01 '16 at 12:02
  • @Faloude: That's then determined by compiler settings (either on the command line on in your project settings in your IDE), see https://msdn.microsoft.com/en-us/library/x3eht538.aspx – Joren Sep 01 '16 at 12:05
  • 1
    @Faloude If you didn't disambiguate it, as Joren described how to do, then the code wouldn't compile; it would specifically tell you that the entry point is ambigous. – Servy Sep 01 '16 at 14:55
2

But the class MainClass has never been initialised. Why is it executed

It doesn't need to be, as Main is static as others have pointed out.

When a managed assembly is compiled, there is section in it's header which tells .NET runtime where is the Main method defined and is set as the Entry Point to the program. You can see it opening a managed .EXE is ILDASM:

TypeDef #3 (02000004)
-------------------------------------------------------
TypDefName: ConsoleApplication1.Program  (02000004)
Flags     : [NotPublic] [AutoLayout] [Class] [AnsiClass] [BeforeFieldInit]  (00100000)
Extends   : 01000010 [TypeRef] System.Object
Method #1 (0600000c) [ENTRYPOINT] <--- This
-------------------------------------------------------
    MethodName: Main (0600000C)
    Flags     : [Private] [Static] [HideBySig] [ReuseSlot]  (00000091)
    RVA       : 0x000021cc
    ImplFlags : [IL] [Managed]  (00000000)
    CallCnvntn: [DEFAULT]
    ReturnType: Void
    1 Arguments
        Argument #1:  SZArray String
    1 Parameters
        (1) ParamToken : (0800000c) Name : args flags: [none] (00000000)

The runtime is the one in charge of invoking your Main method.

If you really want to understand how the runtime is initialized, check out What happens when a .net application is started?

Community
  • 1
  • 1
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
1

The Main Method is the entrance to the application. It doesn't need to be initialized. Any other class that you want to use in the method will need to be initialized except for some classes like static.

Rajdeep
  • 788
  • 7
  • 26
1

In simple words, you need an entry point (from OS) to your code.so public static void Main(string[] args) is made as that entry point main thread , if you see java ,c#,c++ all programs paradigm follows almost same convention. Below in terms of compiler I) public-anyone can access Ii)static-no need yo create instance and can be called directly and only once the m memory will be allocated iii) void- returns empty to the called function (OS) iv) Main -unique function name and as per convention it is an entry point to the application.

Hameed Syed
  • 3,939
  • 2
  • 21
  • 31
1

Main method specifies the entry point of the application. This method can be accessed using classname.methodname() syntax since it is static method.

Sagar
  • 454
  • 10
  • 22
1

Main is C# entrypoint. It's the CLR that is responsible for executing the program.When compiled to IL it is marked as .entrypoint which is what the CLR uses to identify the method to start.

Here is a snapshot of IL(Intermediate Language) of your code

.class private auto ansi beforefieldinit Test.MainClass
   extends [mscorlib]System.Object
{
 .method public hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       13 (0xd)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "Hello World!"
  IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000b:  nop
  IL_000c:  ret
} // end of method MainClass::Main
Rohit
  • 10,056
  • 7
  • 50
  • 82