【问题标题】:Should a class that will run only once contain a static constructor?只运行一次的类是否应该包含静态构造函数?
【发布时间】:2015-07-08 20:19:19
【问题描述】:

我开始学习使用 C# 进行 OOP 编程。 关于设计,对我来说,对我的程序的主类使用static 构造函数是有意义的,考虑到这个类包含只能运行一次的代码(我的整个程序非常简单,只包含一个 .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;
        }
    }


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

【问题讨论】:

  • 调用代码是什么样子的?
  • @Legends 我猜这是这里程序的入口点;)
  • 可能没有直接关系,而是有一个带有程序入口点Main和代码的类,有两个单独的类,一个带有入口点(程序) 另一个与您的业务逻辑有关。稍后您可以决定将该类设为静态还是非静态。
  • 您认为与在 Main 中而不是构造函数中使用相同的代码相比,这使您获得了什么?
  • 第一种方式不好,因为 Program 类和 Main 函数交互的方式不寻常。第二种方法更糟糕,因为它不必要地依赖于 CLR 在执行的某个点自动进行的函数调用,而不是在代码中进行实际可见的调用,这更清晰,这在这个程序中是完全没有必要的。

标签: c# oop constructor static-constructor


【解决方案1】:

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

但是在第一个实例中,值status 是基于实例的。因此,只有Program 的实例具有状态值。因此,如果status 是一个基于实例的字段,其中Program 的多个实例应该保持各自的status 字段值,那么您应该使用第一个示例。

【讨论】:

    【解决方案2】:

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

    还要尽量避免在构造函数中做“工作”。构造函数是用来构造实例的,仅此而已。

    所以在这两种情况下,我都会将功能转移到方法中。然后该方法可以有一个实际的返回值,而不是设置一个属性。由于您没有维护任何状态(Program.status 然后转换为返回值),您可以安全地将该方法设为静态。

    【讨论】:

    • 谢谢,解释得很清楚。您是否建议我将代码放在 Main 方法中,就像有人在 cmets 中建议的那样?
    • 只要它不会变得太大,当然可以。但无论哪种方式,我担心您仍然会创建程序程序而不是 OOP 程序。
    【解决方案3】:

    OP 可能正在寻找单例模式。 我个人的观点是,如果一个类只会被实例化一次,那么它首先就没有理由成为一个类,如果这样一个类的所有方法都恢复为静态 C,那么调用开销就会更少功能 - 但这只是我的看法。

    【讨论】:

      猜你喜欢
      • 2011-02-09
      • 1970-01-01
      • 1970-01-01
      • 2020-02-15
      • 2022-07-07
      • 2014-08-03
      • 2011-10-26
      • 2012-09-04
      • 1970-01-01
      相关资源
      最近更新 更多