【问题标题】:Auto-implemented properties with non null guard clause?具有非空保护子句的自动实现属性?
【发布时间】:2011-10-10 00:47:52
【问题描述】:

我同意 Mark Seeman 的观点,即 Automatic Properties are somewhat evil 因为它们破坏了封装。不过我确实喜欢它们带来的简洁语法、可读性和便利性。

我引用:

public string Name { get; set; }

代码 sn-p 的问题不在于它包含太多 仪式。问题是它破坏了封装。其实

“[...] getter 和 setter 没有实现封装或信息 隐藏:它们是一种语言合法的违反它们的方式。”

James O. Coplien 和 Gertrud Bjørnvig。精益架构。威利。 2010 年。 134.

大多数时候,添加非空保护子句对于属性设置器来说已经足够了,我想知道是否有比以下方法更好的方法。更好,我的意思是更简洁/更少重复的方式。

使用代码契约:

private string _username;
public virtual string Username
{
    get { return _username; }
    set 
    {  
        Contract.Requires(value != null);
        _username = value; 
    }
}

使用原版 .NET:

private string _username;
public virtual string Username
{
    get { return _username; }
    set 
    {
        if (value == null) throw new ArgumentNullException("Username");
        _username = value; 
    }
}

【问题讨论】:

  • 老实说,这不可能。但是很想听听别人的意见。

标签: c# code-contracts automatic-properties guard-clause


【解决方案1】:

【讨论】:

  • 我感觉到 PostSharp 会出现。我想知道使用 Castle Interceptors 和自定义属性会获得多少性能损失。
【解决方案2】:

我会假设属性只是从用户的角度来看的内存缓冲区。仅当在用户代码中调用方法(操作)时,才应检查属性缓冲区的有效性(例如,空检查会引发异常)。

如果分配的数据无效(在您的算法设计中),您的属性设置器应该向内部成员放置一个无效值。错误检查和返回应该来自使用该属性值的方法

【讨论】:

  • 我同意这一点,我倾向于不验证进入属性 - 但验证何时使用该属性。
  • 我明白你的意思,但我并不真正同意这一点,因为这违反了我所信奉的“快速失败”原则。
  • @Can 我倾向于忽略任何不是 UI 的东西。尤其是基于属性的类,例如 Xaml 事物。属性有效性可能与尚未设置的另一个属性的内容有关。
  • @Adam,我认为对于 DTO 来说这没问题,但对于域对象的封装和状态验证非常重要。
  • @Can我没说他们不是。不对属性进行设置验证不会破坏这一点,只要稍后完成。
【解决方案3】:

我只引用Code Contracts 手册,第 2.3.1 节:

public int MyProperty { get; private set ; }

[ContractInvariantMethod]
private void ObjectInvariant () 
{
      Contract. Invariant ( this.MyProperty >= 0 );
      ...
}

【讨论】:

  • 这似乎是最接近我正在寻找的东西,尽管它不是最佳的,因为它将在每个 getter/setter 上运行..
猜你喜欢
  • 2013-02-11
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 2015-09-25
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多