如何确保在首次使用之前已初始化所有类字段

本文关键字:初始化 字段 何确保 确保 | 更新日期: 2023-09-27 18:35:10

假设我有一个做一些计算的类。这组计算需要一组参数作为输入。

public class Calculator
{
private CalculatorConfig _config;
public Calculator(CalculatorConfig config)
{
_config = config;
}
public Result Calculate(object obj){}
}

我的计算器配置类非常简单:

public class CalculatorConfig
{
      public double param1;
      public double param2;
      ...
}

我非常简单地初始化它

var config = new CalculatorConfig();
config.param1 = val;
....
var calculator = new Calculator(config);

我遇到的困境是,此类的用户可能会忘记初始化一些可能导致奇怪行为的字段。可能有意义的解决方案是将字段转换为属性,并且对于每个私有字段都有一个额外的布尔值,该布尔值将保存字段是否已初始化的信息。我还可以创建一个巨型构造函数,它将所有字段作为参数。

在这种情况下,您会选择什么方法?

谢谢

如何确保在首次使用之前已初始化所有类字段

我将使用另一种方法。

  • 将另一个名为 Check 的方法(可能是内部方法)添加到 CalculatorConfig 类中。
  • 在执行 Compute 方法的过程中调用此方法。
  • 在 Check 方法中验证每个参数并抛出自定义异常是出了问题

    public class CalculatorConfig 
    { 
      public double param1; 
      public double param2; 
      ... 
      internal void Check()
      {
           if(param1 == 0.0)
               throw new ArgumentException("Configuration error: param1 is not valid!");
           if(param2 == 0.0)
               throw new ArgumentException("Configuration error: param2 is not valid!");
           .... // other internal checks
      }
    } 
    
    public class Calculator 
    { 
        private CalculatorConfig _config; 
        public Calculator(CalculatorConfig config) 
        { 
            _config = config; 
        } 
        public Result Calculate(object obj)
        {
            // Throw ArgumentException if the configuration is not valid
            // Will be responsability of our caller to catch the exception
            _config.Check();
            // Do your calcs
            .....
        } 
    } 
    

如果所有参数都是绝对必需的,那么我会使用"巨型构造函数"选项。 这是一种更干净的方法来确保所有内容都已初始化,并且您不必添加额外的布尔属性并处理未初始化的情况。如果其中一个布尔值包含假值,你会怎么做?如何强制类的用户返回并添加这些值,除非使用某种异常处理?构造函数将简单地确保这些事情甚至不会在编译时发生,而不是在运行时发生。

我认为您的配置参数应该readonly(可以说是private,但可以通过属性访问)。然后,将警告设置为标记为错误。然后,当您无法初始化这些变量之一时,您将收到编译时错误

字段CalculatorConfig.param1永远不会分配到,并且将始终具有其默认值。

现在,您已经在编译时发现了问题。

在声明中设置默认值:

public class CalculatorConfig
{
      public double param1 = 1.0; // a default value chosen by you
      public double param2 = 2.0; // a default value chosen by you
}

或者更OO的解决方案:使用属性而不是公共字段,然后在创建实例时设置默认值:

public class CalculatorConfig
{
      public double param1 {get;set;}
      public double param2 {get;set;}
      public CalculatorConfig()
      {
          InitParams();
      }
      private void InitParams()
      {
          param1 = 1.0;
          param2 = 2.0;
      }
}