Why is the class “Program” declared as static?

前端 未结 4 1057
后悔当初
后悔当初 2020-12-31 00:14

When you create a WinForm App, you get an automatically generated template of Program class in the Program.cs file.

Which look

相关标签:
4条回答
  • 2020-12-31 00:46

    My question is, why is the Program class declared as static?

    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 Programinherit from a base class that would implement handling of Application.ThreadException and AppDomain.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.

    0 讨论(0)
  • 2020-12-31 00:53

    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.

    0 讨论(0)
  • 2020-12-31 01:00

    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.

    0 讨论(0)
  • 2020-12-31 01:06

    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.

    0 讨论(0)
提交回复
热议问题