运行 只包含一次的 class 是否应该包含静态构造函数?

Should a class that will run only once contain a static constructor?

我开始使用 C# 学习 OOP 编程。 关于设计,考虑到这个 class 包含的代码只会 运行 一次(我的整个程序非常简单,由一个 .cs 文件组成。

例如,下面是使用普通构造函数的示例代码:

class Program
    {
        const string file = @"C:\Program Files (x86)\myapp\log.txt";
        int status;

        static int Main(string[] args)
        {
            var myObj = new Program();
            return myObj.status;            
        }

        public Program()
        {
            int retCode;

            try {
                //  lots of procedures using the file

                retCode = 0;   // ok
            }
            catch (Exception ex) {
                Console.WriteLine(ex.Message);

                retCode = 999; // specific error
            }

            status = retCode;
        }
    }

这里遵循相同的结构,但使用 static 构造函数,因为我认为它已经足够了。请注意 status 访问权限也已更改。

class Program
    {
        const string file = @"C:\Program Files (x86)\myapp\log.txt";
        static int status;

        static int Main(string[] args)
        {
            return Program.status;
        }

        static Program()
        {
            int retCode;

            try {
                //  lots of procedures using the file

                retCode = 0;
            }
            catch (Exception ex) {
                Console.WriteLine(ex.Message);

                retCode = 999;
            }

            status = retCode;
        }
    }


问题:我的假设是否正确,使用第二个代码而不是第一个代码?或者我错过了什么? 换句话说:哪个更好(被认为是更好的设计)?在这种情况下,静态构造函数是否有一些基础知识会给我带来麻烦?

所提供的代码做的事情完全相同,除了在第一个实例中您创建对象 Program 而不是使用静态成员。这将为您的应用程序创建额外的开销。现在在这种情况下,确实没有理由选择这两种方法中的任何一种,因为开销可以忽略不计。

然而,在第一个实例中,值 status 是基于实例的。因此只有 Program 的实例具有状态值。因此,如果 status 是一个基于实例的字段,其中 Program 的多个实例应该维护它们自己的 status 字段值,那么您应该使用第一个示例。

尽量避免使用静态构造函数。与实例构造函数不同,您不能主动调用静态构造函数 - 它是 运行 当类型第一次被使用时(这可能会由于优化甚至混淆而改变)。

同时尽量避免在构造函数中执行 "work"。构造函数旨在构造实例,仅此而已。

所以在这两种情况下,我都会将功能移至方法中。然后该方法可以具有实际的 return 值,而不是设置 属性。由于您不维护任何状态(Program.status 然后变成 return 值),您可以安全地使该方法静态化。

OP 可能正在寻找单例模式。 我个人的观点是,如果 class 只会被实例化一次,那么它一开始就没有理由成为 class,并且如果这样的 class 被还原为静态 C 函数 - 但这只是我的意见。