When you create a WinForm
App, you get an automatically generated template of Program
class in the Program.cs
file.
Which look
My question is, why is the
Program
class declared asstatic
?
As you note, it doesn't have to be. In fact, in my version of Visual Studio (Visual Studio 2015 Enterprise Update 1) the default program for "Console Application" is
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
}
}
}
But wait, why is Main
static again?
This answer does an excellent job of explaining why Main
must be static. In short, the answer states that Main
must be static because the alternative is that the CLR would have to call the constructor on Program
in order to call Program.Main
. But think about it, nothing happens before the entry point so no such constructor can be called!
The reason for the question is that I thought it could be nice to have
Program
inherit from a base class that would implement handling ofApplication.ThreadException
andAppDomain.CurrentDomain.UnhandledException
instead of implementing it more or less the same for all of my projects.
This is a really good idea; DRY is one of my favorite programming principles. However, to do it in the way you were thinking, Program
would need to derive from a base object of type, say, ProgramBase
and call some sort of protected method. Something like this perhaps?
internal class Program : ProgramBase
{
static void Main(string[] args)
{
// ERROR: "an object reference is required for the non-static
// field, method, or property ProgramBase.MainWrapper();"
MainWrapper();
}
protected override void DoMain()
{
// do something
}
}
internal abstract class ProgramBase
{
protected void MainWrapper()
{
try
{
// do some stuff
DoMain();
}
catch(...)
{
// handle some errors
}
}
protected abstract void DoMain();
}
The problem arises that to solve the problem with inheritance, Program.Main()
must call some sort of non-static method.
OK, now lets solve the problem a different way. Let's create an ApplicationBase
abstract class for applications of different types to derive from.
class Program
{
static void Main(string[] args)
{
var myApp = new MyApplication();
myApp.RunApp();
}
}
public class MyApplication : ApplicationBase
{
protected override void DoRunApp()
{
// do my stuff
}
}
public abstract class ApplicationBase
{
public void RunApp()
{
try
{
// create AppDomain, or some other construction stuff
// do some stuff
DoRunApp();
}
catch(...)
{
// handle some errors
}
catch(...)
{
// handle some other errors
}
}
protected abstract void DoRunApp();
}
NOW we're getting somewhere. Depending on what you are creating in your setup/creation phase, your DoRunApp()
signature may change but this sort of template should accomplish what you're looking for.
Thanks for reading.
The reason for it to be static is, because it only has static methods and nothing else.
If you would now add interfaces, base classes and non static methods/properties/members you would have to create an instance of that class to use them (which is forbidden because of the static class
). Which is still fine, and could even be done in the static Main method, but it could be misleading or is not the intended purpose of that class. I would create a MyApplication class anway, instance it in the static Main and create my Form from there.
Regarding your Exception handlers. You can still create a manager class that does that for you, which you just call from your Main and can be reused in all your programs.
Avoid over-thinking this. This code just comes out of the project template, pre-cooked in C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\ProjectTemplates\CSharp\Windows\1033\WindowsApplication\Program.cs
There's nothing to stop you from modifying that code, removing the static keyword is entirely reasonable if that's the way you prefer it. There is a bit of logic to it, you after all have only one program so declaring it static does make sense. But compare it to the project template for a Console mode app, It also declares a Program class but didn't make it static. It doesn't make extra sense at all to make that class not static for a console app.
There are certainly other good reasons to modify the project template code. It for example puts the Dispose() method for a Form derived class in the Designer.cs file. Not a great place for it, the "never modify designer generated code" rule does get Winforms programmers paralyzed. Moving that method into the Form.cs file and then modifying it is just fine.
This is merely "most likely to fall in the pit of success" code. Never hesitate to change it.
It just follows a design guideline, that classes that contain only static
methods should be marked as static
. More information can be found here.
There is no problem in making your Program
class not static, the only thing that is required is the static Main
method as an entry point, as you've already noticed. You can add instance methods to the Program
class, instantiate it and use as any other class. However this is not a clear way, as this violates the Single Responsibility Principle. Program
's responsibility is to provide an entry point for the application, so it shouldn't do anything more. For this task it needs only one static
method called Main
. And as it contains only static
methods, it should be marked as static
to conform to C# coding guidelines.
In general, it is convenient to know that a class is static
, so you know at first glance that it contains only static
methods. It is a very readable way of expressing how a class should be used. In this example it isn't very essential, as no one uses Program
explicitly, however for the sake of strictness it should be static
.