带有非空保护子句的自动实现属性?
我确实同意 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我将引用代码合同手册,§ 2.3.1:
I'll just quote the Code Contracts manual, § 2.3.1:
您可以使用 PostSharp 的方面通过空检查来装饰属性设置器:
http://www.sharpcrafters.com/blog/post/5-Ways-That-Postsharp-Can-SOLIDify-Your-Code-Lazy-Loading-of-Dependency.aspx
如何创建一个方面检查postsharp中类中所有方法的空引用
http://magpie.sytes.net/jesperhogstrom/2010/11/compiler-safe-null-checking-of-arguments-with-aspects/
You could use aspects from PostSharp to decorate the property setter with a null check:
http://www.sharpcrafters.com/blog/post/5-Ways-That-Postsharp-Can-SOLIDify-Your-Code-Lazy-Loading-of-Dependencies.aspx
How to create an aspect checking for null references on all methods in a class in postsharp
http://magpie.sytes.net/jesperhogstrom/2010/11/compiler-safe-null-checking-of-arguments-with-aspects/
从用户的角度来看,我认为属性只是内存缓冲区。仅当在用户代码中调用方法(操作)时,才应检查属性缓冲区的有效性(例如,空检查会引发异常)。
如果分配的数据无效(在您的算法设计中),您的属性设置器应该为内部成员放置一个无效值。错误检查和返回应该来自使用此属性值的方法
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