Is it necessary to use static void main()
as the entry point function in C#, or can we use some other function?
Why is main()
static?
7 Answers
Before C# 9, the entry point had to be declared explicitly. C# 9 introduces top level statements which allow the entry point to be generated implicitly. (Only a single source file in a project can include top-level statements, however.)
When the entry point is declared explicitly, it has to be Main
. It's static because otherwise the CLR would need to worry about creating an instance of the type - which means you'd presumably have to have a parameterless constructor, even if you didn't want an instance of the type, etc. Why would you want to force it to be an instance method?
Even with top-level statements, your actual program still has an entry point called Main
- it just doesn't appear in your source code.

- 1,421,763
- 867
- 9,128
- 9,194
-
12@anish, because it has to be something and Public Static Void Quack() did not sound as good. Why try to walk through a wall when there is a door right there? – Cos Callis May 10 '11 at 18:35
-
1
-
1@Anish. The CLR specifies that there has to be an entry point, the C# language specification identifies the entry point as Main(). VB.Net uses main() also, but it is not case sensitive. Other languages may specify a different entry point, though I don't know of one that uses something other than 'main' or 'Main'. – Cos Callis May 10 '11 at 18:55
-
-
@Sandeep: Absolutely - the compiler basically decorates the assembly with metadata pointing to that method, saying "Start here!" – Jon Skeet May 11 '11 at 09:02
-
In that case, wouldn't it make sense to let us add the attributes ourselves, and point the entry point to a method with any name? – julealgon Nov 28 '17 at 19:26
-
3@juleagon: That would be a reasonable option, and I don't know the reason for sticking with a well-known name instead, although it does mean that to write Hello World you don't need to understand attributes... – Jon Skeet Nov 28 '17 at 19:59
-
That's true @JonSkeet, but they could always either default to the current known name if you don't specify the attribute, or just automatically add the attribute on project creation right? Very weird hardcoding decision considering other parts of the framework. I hate these inheritances from the C++ world :( – julealgon Dec 08 '17 at 13:46
-
1@julealgon: It feels reasonably pragmatic to me, to be honest. Put it this way: it really hasn't caused me any pain in all the time I've been writing C#. – Jon Skeet Dec 08 '17 at 13:47
-
**This answer is not up to date.** Please refer to [my answer](https://stackoverflow.com/a/69912459/9988162) instead. – Despacito 2 Jan 10 '22 at 14:38
-
1@Despacito2: I've now accepted the edit, although I'll edit it again to refer to the MS docs. – Jon Skeet Jan 10 '22 at 14:46
-
1@Despacito2: Personally I'm fine with proposing an edit to the accepted answer. Others may have a different view. (Basically I don't have time to review/edit all my C# posts every time a new language version comes out...) – Jon Skeet Jan 10 '22 at 15:08
-
Appreciate you taking the time to look at the edit and deciding to accept it @Jon, from an outside reviewer perspective it makes sense for such an edit to simply be a new answer (especially with the outdated answer functionality in the works), but always happy to see them approved by the OP. – Nick is tired Jan 10 '22 at 20:07
-
@Nick I appologize for the inconvience I may have caused. I simply didn't know the best approach as to how to get attention to the new feature since the author of this question seems to have gone inactive. I'll take your advice for future posts. – Despacito 2 Jan 10 '22 at 20:19
-
1@Despacito2 It's hit or miss, some authors don't mind their answers linking to another when a new feature is added, others do. As for us reviewers... we can't really tell what the author would want and have to go with what we consider best, even if sometimes that means the OP overrides what we do. No need to apologise. – Nick is tired Jan 10 '22 at 20:22
Yes, for a C# application, Main()
must be the entry point.
The reason is because that's what the designers of the language decided to be what to look for as an entry point for your program. They could just as well have used a totally different approach to find the entry point, e.g. using meta data, or instantiating an object for you (which would require a parameterless constructor). Another reason for naming it void main()
is that it's intuitive for users coming from other languages.

- 8,758
- 11
- 40
- 62

- 32,730
- 15
- 85
- 123
static void Main()
is the necessary entry point for any "Executable" (.EXE) to be created in C#. A library (or .DLL) can have other entry points.
The method is static because that is required in order to access the method without having an instance of the object to address. In order to invoke the method (starting point) from outside the application, a static method is required.

- 8,758
- 11
- 40
- 62

- 5,051
- 3
- 30
- 57
-
1What is considered a good practice to mark an entry poing of a library? There may be several public classes, how to show user which is the key? Namespace? Name of the class that corresponds to dll's name? – ZuoLi Dec 06 '16 at 15:09
Since C# 9 you can now remove the boilerplate through Top-level statements.
Before:
using System;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
Newly possible:
using System;
Console.WriteLine("Hello World!");
Source: https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9#top-level-statements
If you insist on using the Main function as the entry point, more information can be found here

- 444
- 2
- 10
The Main
method might be what you consider as the entry point of an application but in c# as far as i know methods can't be defined directly in namespaces which means it has to be within a class. The real first executed thing then is the static constructor of the class containing the Main
method
using System;
namespace test
{
class Program
{
static Program()
{
Console.WriteLine("static constructor");
}
public static void Main(string[] args)
{
Console.WriteLine("Main method");
}
}
}
Outputs static constructor
first and then Main method

- 1,894
- 11
- 26
The required entry point is actually:
static void Main(string[] args); // note capitalization and arguments
The reason that Main
must be static is that non-static objects must be constructed before you call any methods on them. Since Main
is the entrance point of the program, who's going to call its constructor?
(Yes, you could have the CLR require that the class with Main
contain a default parameterless constructor, and make the CLR call that constructor during global startup. But that's extra work, and in practice it's easier to just require that Main
be static.)

- 40,684
- 18
- 101
- 169
-
2The required entry point is actually... very flexible. You can return an int from it and you can omit the arguments – R. Martinho Fernandes May 10 '11 at 18:55
-
If we do like this `Public void Main(string[] args)` and than invoke it by creating it's instance from outside the application isn't that work? – Sandeep May 11 '11 at 08:45
static int Main(string[] args)
is static because it reduces the number of potential steps the runtime needs to go through before it can start executing the entry point of your program (run class's static constructor, run class's static Main... versus run class's static constructor, instantiate the class into some location that's undefined, run instance's constructor, then run instance's Main method). You'd have to write boilerplate code to store this
into an instance variable you could use (and likely to keep it from going out of referential scope which would enable it to be garbage-collected) which would also tend to increase the reference count and require a little more memory and pricessing for not much gain.
It's named Main because C# is strongly reminiscent of Java in its design, and Java uses the name Main, which itself derives from a slight differentiation (case is a thing!) from C and C++.

- 649
- 6
- 25