在课堂上使用访问器是不好的做法吗?

时间:2014-01-30 16:29:52

标签: c# class field encapsulation accessor

所以我有一个简单的类,User,就像这样(忽略可怕的空白使用,想让它简要在线阅读):

public class User
{
  private string username;
  public string Username 
  {
    get
    {
      return username;
    }set{
      if(Validate.usernameIsValid(value)){username = value;}
      else{throw new InvalidArgumentException("Username is invalid");}
    }
  }
  //some more fields

  public User(String argUsername)
  {
    this.Username = argUsername;
    //OR validate again before:
    username = argUsername;
  }

}

使用类中的公共访问器来使用其验证更好吗?或者这是不好的做法,在这种情况下,我应该在设置私人username字段之前重新验证吗?

5 个答案:

答案 0 :(得分:1)

答案取决于数据的来源。由于使用setter后面的驱动点是为了避免重复验证代码,因此有两个基本情况:

  • 当数据来自您的类外(例如通过方法参数,如您的示例中),那么您应该调用setter,它将为您执行验证。
  • 当数据在您准备分配时已“消毒”时,请直接转到该变量,绕过验证。

前一种情况延伸到您阅读用户输入的情况。

后一种情况包括从快照恢复对象状态或在内部生成对象状态的情况。例如,如果您的setter具有null /空字符串验证,并且您的方法想要将字符串设置为GUID的字符串表示形式,则可以跳过设置器。

答案 1 :(得分:1)

在大多数情况下,我使用公共财产,因为通常需要在那里完成所有工作。但也有例外(例如,如果验证需要进行一次)。所以你一般都说不出来。

答案 2 :(得分:1)

我建议使用公共设置器而不是变量的本地设置,因为只有一个地方 - 设置器 - 处理与验证相关的所有逻辑。但是,只有在类中的每个位置和所有派生版本严格遵循此约定时,这才有效。

我们不能假设成员变量不会在类中的其他地方(或者它的派生版本,如果它受到保护)被操纵。想象一下,另一个程序员调试与用户名验证相关的错误。在搜索时发现所有验证都是通过setter进行的,这是一个令人愉快的惊喜 - 所以她没有调试多个验证逻辑。

答案 3 :(得分:1)

在类中使用公共访问器是可以的,也可以使用任何公共方法。 (毕竟,属性只是getter / setter方法的语法糖。)

如果从类中访问属性与从外部访问属性具有相同的语义,则

在内部使用访问器可能是首选。

此外,访问器为处理常规和自动实现的属性提供了一致的方法。 (自动实现的只是不显式公开支持字段。)

此外,在构造函数之外,几乎可以肯定,访问器应该用于虚拟属性。

需要直接使用支持字段,而不是后门属性操作。

但是没有一般规则选择哪种方法。

答案 4 :(得分:0)

实际上你做得很好,自封装字段让你可以轻松地根据你的需要设置属性值:例如看看这个:

private readonly ProductManufacturer _productManufacturer = new  ProductManufacturer();
private readonly IList<ProductCategory> _productCategories = new List<ProductCategory>();


public ProductManufacturer ProductManufacturer
{
    get { return _productManufacturer; }
}

public IEnumerable<ProductCategory> ProductCategory
{
    get { return _productCategories; }
}

现在您可以在其他地方获取产品类别列表的列表,或者您只能对产品类别执行其他操作,如下所示:

 public void AddProductCategory(ProductCategory productCategory)
        {
            _productCategories.Add(productCategory);
        }

有关自封装字段的更多信息,请查看:

http://www.refactoring.com/catalog/selfEncapsulateField.html