Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何确保在首次使用前已初始化所有类字段_C#_Initialization - Fatal编程技术网

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

C# 如何确保在首次使用前已初始化所有类字段,c#,initialization,C#,Initialization,比如说我有一个做一些计算的类。这组计算需要一组参数作为输入 public class Calculator { private CalculatorConfig _config; public Calculator(CalculatorConfig config) { _config = config; } public Result Calculate(object obj){} } 我的CalculatorConfig类非常简单: public class CalculatorConfi

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

public class Calculator
{
private CalculatorConfig _config;
public Calculator(CalculatorConfig config)
{
_config = config;
}

public Result Calculate(object obj){}
}
我的CalculatorConfig类非常简单:

public class CalculatorConfig
{
      public double param1;
      public double param2;
      ...
}
我非常简单地初始化它

var config = new CalculatorConfig();
config.param1 = val;
....
var calculator = new Calculator(config);
我遇到的难题是,这个类的用户可能忘记初始化一些字段,这可能会导致奇怪的行为。 有意义的解决方案是将字段转换为属性,对于每个私有字段,都有一个额外的布尔值,用于保存字段是否初始化的信息。 我还可以创建一个megaconstructor,它将所有字段作为参数

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


谢谢

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

在声明中设置默认值:

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

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

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;
      }
}

我将使用另一种方法

向CalculatorConfig类添加另一个方法,可能是一个名为Check的内部方法。 在计算方法的执行过程中调用此方法。 在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
        .....
    } 
} 

我认为您的配置参数应该是只读的,可以说是私有的,但可以通过属性访问。然后,将警告设置为标记为错误。然后,当您未能初始化其中一个变量时,您将得到一个编译时错误

字段CalculatorConfig.param1从未分配给,并且始终具有其默认值


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

如果我们正在设计将在不同环境中用作库或框架的类,这种方法有效吗?我不明白这有什么关系。我认为“将警告设置为标记为错误”只有在您是propre API的客户时才有效,如果您将代码作为dll分发,以便与不同的客户机一起使用,将会发生什么情况。我个人在以前的项目中的经验是,默认值是有害的。我们不得不处理一些奇怪的结果,因为有人忘记初始化一些值,而使用了默认值。我认为,当有人忘记初始化参数时,应该受到最严重的惩罚——例外。