强制开发人员使用特定的构造函数

时间:2009-05-22 20:02:15

标签: c# .net

我有以下课程

  public class UIControl
  {
    public string FName{ get; set; }
    public HtmlInputCheckBox SelectCheckBox { get; set; }
    public bool OverrideSelect { get; set; }

    //Want to throw an ApplicationExceptioh if developer uses this constructor and passes
    //chkSelect = null
    public UIControl(string sFieldName, HtmlInputCheckBox chkSelect)
    {
      this.FName= sFieldName;
      this.SelectCheckBox = chkSelect;
    }

    public UIControl(string sFieldName, HtmlInputCheckBox chkSelect, bool overrideSelect)
      : this(sFieldName, chkSelect)
    {
      OverrideSelect = overrideSelect;
    }
  }

我想确保开发人员仅在chkSelect不为null时才使用第一个构造函数。

我想做一个:

throw new ApplicationException("Dev is using the incorrect constructor");

9 个答案:

答案 0 :(得分:13)

您可以使用私有构造函数:

public UIControl(string sFieldName, HtmlInputCheckBox chkSelect) 
    : this(sFieldName, chkSelect, false, false)
{      
}    

public UIControl(string sFieldName, HtmlInputCheckBox chkSelect, 
     bool overrideSelect)      
    : this(sFieldName, chkSelect, overrideSelect, true)    
{      
}  

private UIControl(string sFieldName, HtmlInputCheckBox chkSelect, 
   bool overrideSelect, bool allowOverride)      
{      
    if ((!allowOverride) && (chkSelect == null)) 
         throw new ArgumentException(...);
    this.FName= sFieldName;      
    this.SelectCheckBox = chkSelect;    
    OverrideSelect = overrideSelect;    
}  

有许多变体,但作为一般规则,具有较少特定构造函数调用更具体的变体。例如,以下内容也适用于您的情况:

public UIControl(string sFieldName, HtmlInputCheckBox chkSelect)    
    : this(sFieldName, chkSelect, false)
{      
   if (chkSelect == null) throw ...
}    

public UIControl(string sFieldName, HtmlInputCheckBox chkSelect, 
     bool overrideSelect)    
{      
    this.FName= sFieldName;      
    this.SelectCheckBox = chkSelect;    
    this.OverrideSelect = overrideSelect;    
}

答案 1 :(得分:3)

什么难?

public UIControl(string sFieldName, HtmlInputCheckBox chkSelect)
{
    if (chkSelect == null)
    {
        throw new ApplicationException("Dev is using the incorrect constructor");
    }

    this.FName= sFieldName;
    this.SelectCheckBox = chkSelect;
}

答案 2 :(得分:3)

喜欢这个吗?

//Want to throw an ApplicationExceptioh if developer uses this constructor and passes
//chkSelect = null
public UIControl(string sFieldName, HtmlInputCheckBox chkSelect)
{
  if (chkSelect == null)
  {
    throw new ArgumentException("chkSelect cannot be null when using this constructor");
  }
  this.FName= sFieldName;
  this.SelectCheckBox = chkSelect;
}

答案 3 :(得分:2)

更好的做法(或更常见的做法,因为C#在4.0之前没有默认参数)让较少的特定构造函数使用更具体的构造函数,反之则不然。然后,您可以使用具有可空bool的私有构造函数。如果您能够重写它们,请尝试以下操作:

public UIControl(string sFieldName, HtmlInputCheckBox chkSelect)
  : this(sFieldName, chkSelect, null)
{
}

public UIControl(string sFieldName, HtmlInputCheckBox chkSelect, bool overrideSelect)
  : this(sFieldName, chkSelect, overrideSelect)
{
}

UIControl(string sFieldName, HtmlInputCheckBox chkSelect, bool? overrideSelect)
{
  if (!overrideSelect.HasValue && chkSelect == null)
  {
      throw new ArgumentException("chkSelect");
  }
  FName = sFieldName;
  SelectCheckBox = chkSelect;
  OverrideSelect = overrideSelect ?? false;
}

答案 4 :(得分:1)

为什么不喜欢这个?

public UIControl(string sFieldName, HtmlInputCheckBox chkSelect)
{
    if (chkSelect == null) 
    { 
        throw new ApplicationException("Dev is using the incorrect constructor"); 
    }
    this.FName= sFieldName;
    this.SelectCheckBox = chkSelect;
}

然而,通过运行时错误执行此操作可能是一个坏主意。更好的想法是使用一个根本不带chkSelect参数的重载,或使chkSelect不可为空。

编辑:我现在注意到第二个选择器调用第一个选择器,但第二个选择器唯一做的就是更改OverrideSelect字段的值。为什么不只有一个构造函数,并设置该字段?或者为什么要那个领域呢?几个选择:

// This is now the ONLY constructor you need
public UIControl(string sFieldName, HtmlInputCheckBox chkSelect)
{
    OverrideSelect = (chkSelect == null);
    this.FName= sFieldName;
    this.SelectCheckBox = chkSelect;
}


// You could solve it differently by replacing OverrideSelect with this property:
public readonly bool isChkSelectNull {
    get {
        return (this.chkSelect == null);
    }
}

public UIControl(string sFieldName, HtmlInputCheckBox chkSelect)
{
    this.FName= sFieldName;
    this.SelectCheckBox = chkSelect;
}

答案 5 :(得分:0)

从.Net 4.0获取Spec#或Contracts并使参数不可为空

答案 6 :(得分:0)

基于OP的最新信息:

public class UIControl
{
    //Want to throw an ApplicationException if developer uses this constructor and passes
    //chkSelect = null
    public UIControl(string sFieldName, HtmlInputCheckBox chkSelect)
    {
      if (chkSelect == null)
      {
        throw new ApplicationException("Dev is using the incorrect constructor");
      }
      this.FName= sFieldName;
      this.SelectCheckBox = chkSelect;
    }

    public UIControl(string sFieldName, HtmlInputCheckBox chkSelect, bool overrideSelect)
    {
      this.FName= sFieldName;
      this.SelectCheckBox = chkSelect;  // note: chkSelect MAY be null here.

      OverrideSelect = overrideSelect;
    }
  }

答案 7 :(得分:0)

我不喜欢为程序员问题抛出异常。 Debug.Assert()。

怎么样,而不是抛出异常

答案 8 :(得分:0)

如果chkSelect为null,为什么要抛出异常?

无论如何,要回答你的问题(不一定是你真正需要的东西),我想你可能会倒退。让2参数版本调用3参数版本。

//Want to throw an ApplicationExceptioh if developer uses this constructor and passes
//chkSelect = null
public UIControl(string sFieldName, HtmlInputCheckBox chkSelect)
  : this(sFieldName, chkSelect, chkSelect==null)
{
  if(chkSelect==null) throw new ArgumentNullException("chkSelect");
}

public UIControl(string sFieldName, HtmlInputCheckBox chkSelect, bool overrideSelect)    
{
  this.FName= sFieldName;
  this.SelectCheckBox = chkSelect;
  OverrideSelect = overrideSelect;
}