Avi*_*ner 16 c# static winforms
创建WinForm应用程序时,您将Program在Program.cs文件中获得自动生成的类模板.
看起来像这样:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,为什么这个Program类被声明为static?
如果我删除static声明它仍然可以正常工作.
问题的原因是我认为Program从基类继承可能会很好,它将实现Application.ThreadException和AppDomain.CurrentDomain.UnhandledException的处理,而不是对我的所有项目实现或多或少相同.
Bar*_*zKP 16
它遵循设计准则,只包含static方法的类应标记为static.更多信息可以在这里找到.
使你的Program类不是静态没有问题,唯一需要的是static Main作为入口点的方法,正如你已经注意到的那样.您可以向Program类中添加实例方法,将其实例化并用作任何其他类.然而,这不是一个明确的方式,因为这违反了单一责任原则.Program我们的责任是为应用程序提供一个入口点,所以它不应该做更多的事情.对于此任务,它只需要一个static方法Main.由于它只包含static方法,因此应标记为static符合C#编码指南.
一般来说,知道一个类很方便static,所以你乍一看它只包含static方法.这是表达如何使用类的一种非常易读的方式.在这个例子中,它不是非常必要的,因为没有人Program明确使用,但是为了严格,它应该是static.
我的问题是,为什么这个
Program类被声明为static?
如你所知,它不一定是.实际上,在我的Visual Studio版本(Visual Studio 2015 Enterprise Update 1)中,"控制台应用程序"的默认程序是
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)
{
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是等等,为什么Main再次静止?
这个答案很好地解释了为什么Main必须是静态的.简而言之,答案指出Main必须是静态的,因为替代方案是CLR必须调用构造函数Program才能调用Program.Main.但想想看,在入口点之前没有任何事情发生,所以不能调用这样的构造函数!
问题的原因是我认为
Program从一个基类继承可能会很好,它将实现处理,Application.ThreadException而AppDomain.CurrentDomain.UnhandledException不是为我的所有项目实现它或多或少相同.
这是一个非常好的主意; DRY是我最喜欢的编程原则之一.但是,要按照您的思维方式进行,Program需要从类型的基础对象派生,比方说,ProgramBase并调用某种受保护的方法.也许这样的事情?
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();
}
Run Code Online (Sandbox Code Playgroud)
出现的问题是,要解决继承问题,Program.Main()必须调用某种非静态方法.
好的,现在让我们以不同的方式解决问题.让我们ApplicationBase为不同类型的应用程序创建一个抽象类来派生.
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();
}
Run Code Online (Sandbox Code Playgroud)
现在我们到了某个地方.根据您在设置/创建阶段创建的内容,您的DoRunApp()签名可能会更改,但此类模板应该可以完成您要查找的内容.
谢谢阅读.
避免过度思考这一点.此代码刚出自项目模板,预先在C:\ Program Files(x86)\ Microsoft Visual Studio 11.0\Common7\IDE\ProjectTemplates\CSharp\Windows\1033\WindowsApplication\Program.cs中编写
没有什么可以阻止你修改代码,删除静态关键字是完全合理的,如果这是你喜欢它的方式.它有一点逻辑,你毕竟只有一个程序,所以声明静态确实有意义.但是将它与Console模式应用程序的项目模板进行比较,它还声明了一个Program类但没有使它成为静态.对于控制台应用来说,使该类不是静态的,根本没有任何意义.
修改项目模板代码肯定还有其他充分的理由.例如,它将Surface派生类的Dispose()方法放在Designer.cs文件中.对它来说不是一个好地方,"永远不会修改设计器生成的代码"规则确实让Winforms程序员陷入瘫痪.将该方法移动到Form.cs文件中然后修改它就可以了.
这仅仅是"最有可能陷入成功的关键"代码.毫不犹豫地改变它.
| 归档时间: |
|
| 查看次数: |
14093 次 |
| 最近记录: |