带有非空保护子句的自动实现属性?

发布于 2024-11-25 12:26:21 字数 1004 浏览 1 评论 0原文

我确实同意 Mark Seeman 的观点,即自动属性有些邪恶,因为它们破坏了封装。不过我确实喜欢它们带来的简洁语法、可读性和便利性。

我引用:

public string Name { get; set; }

代码片段的问题不在于它包含太多 仪式。问题是它破坏了封装。事实上

“[...] getter 和 setter 没有实现封装或信息 隐藏:这是一种在语言上合法化的侵犯方式。”

詹姆斯·O·科普林 (James O. Coplien)格特鲁德·比约恩维格。精益架构。威利。 2010 年。 134.

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

使用代码契约:

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

使用 vanilla .NET:

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

I do agree with Mark Seeman's notion that Automatic Properties are somewhat evil as they break encapsulation. However I do like the concise syntax, readability and convenience they bring.

I quote:

public string Name { get; set; }

The problem with the code snippet isn’t that it contains too much
ceremony. The problem is that it breaks encapsulation. In fact

“[…] getters and setters do not achieve encapsulation or information
hiding: they are a language-legitimized way to violate them.”

James O. Coplien & Gertrud Bjørnvig. Lean Architecture. Wiley. 2010. p. 134.

Most of the time, adding a non-null guard clause is good enough for a property setter and I would like to know if there is a better way of doing it than one of the below. By better, I mean in a more concise/less repetitive way.

Using Code Contracts:

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

Using vanilla .NET:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

黯然 2024-12-02 12:26:21

我将引用代码合同手册,§ 2.3.1:

public int MyProperty { get; private set ; }

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

I'll just quote the Code Contracts manual, § 2.3.1:

public int MyProperty { get; private set ; }

[ContractInvariantMethod]
private void ObjectInvariant () 
{
      Contract. Invariant ( this.MyProperty >= 0 );
      ...
}
一刻暧昧 2024-12-02 12:26:21

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

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

I would assume properties are just memory buffer from user point of view. only when a method (action) is invoke in user code, then checks on validity of the properties buffer should be checked (e.g., null checks throws exception).

your properties setter should place an invalid value to the internal member if data assigned is not valid (in your algorithm design). the error check and return should come from the method using this property value

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文