只写属性是否具有实际应用?

Aar*_*ght 48 language-agnostic oop properties

我不知道为什么我开始考虑这个,但现在我似乎无法停止.

在C#中 - 可能还有很多其他语言,我记得Delphi曾经让你这么做 - 编写这种语法是合法的:

class WeirdClass
{
    private void Hello(string name)
    {
        Console.WriteLine("Hello, {0}!", name);
    }

    public string Name
    {
        set { Hello(name); }
    }
}
Run Code Online (Sandbox Code Playgroud)

换句话说,该属性有一个setter但没有getter,它是只写的.

我想我无法想到为什么这应该是非法的,但我从来没有真正在野外看过它,而且我似乎在野外看起来非常精彩/可怕的代码.这似乎是一种代码味道; 似乎编译器应该给我一个警告:

CS83417:属性"名称"似乎完全无用且愚蠢.糟糕的程序员!考虑用方法替换.

但也许我只是没有做足够长的时间,或者为了看到任何有效使用这种结构的例子而在一个太狭窄的领域工作.

是否存在只写属性的现实示例,这些示例要么不能被直接方法调用替换,要么变得不那么直观?

Ðаn*_*Ðаn 16

代码分析(又名FxCop)确实为您提供诊断:

CA1044:Microsoft.Design:因为属性'WeirdClass.Name'是只写的,所以要么添加一个属性getter,其可访问性大于或等于其setter,要么将此属性转换为方法.

  • 很好 - 至少那个告诉我,我不会因为问这个问题而疯狂. (4认同)

dfa*_*dfa 15

我对这个问题的第一反应是:" java.util.Random #setSeed方法怎么样?"

我认为只写属性在几种情况下都很有用.例如,当您不想公开内部表示(封装)时,允许更改对象的状态.java.util.Random是这种设计的一个很好的例子.


Kal*_*see 12

只写属性实际上非常有用,我经常使用它们.这完全是关于封装 - 限制对对象组件的访问.您经常需要为需要在内部使用的类提供一个或多个组件,但没有理由让其他类可以访问它们.这样做只会让你的课更容易混淆("我会使用这个getter还是这个方法?"),更可能是你的课程被篡改或绕过了真正的目的.

有关此问题的有趣讨论,请参阅"为什么getter和setter方法是邪恶的".我不像文章的作者那样关心它,但我认为这是一件好事.我通常使用setter但很少使用getter.

  • 但是为什么只写属性比Set方法更好?(例如SetName(字符串名称).)我会说它不是更好.人们通常希望属性可读.制作一个只写会违反最低惊喜原则.Set方法没有这个问题. (12认同)
  • 您是否可以将物业注入作为DI的一种手段?如果是这样,那么构造函数注入的优势是什么? (6认同)
  • 获取/设置vs属性归结为语法糖.我对他们有利的唯一客观原因是代码简洁和修改实现的灵活性,同时保持"这看起来像一个字段"接口/签名.然后,它很容易陷入构建每个可扩展框架的陷阱,而不仅仅是让事情完成,所以...... (2认同)

RAL*_*RAL 8

我在XNA项目中有类似于以下的代码.正如您所看到的,Scale是只写的,它是有用的并且(合理地)直观,并且读取属性(get)对它没有意义.当然它可以用方法替换,但我喜欢语法.

public class MyGraphicalObject
{
    public double ScaleX { get; set; }
    public double ScaleY { get; set; }
    public double ScaleZ { get; set; }

    public double Scale { set { ScaleX = ScaleY = ScaleZ = value; } }

    // more...
}
Run Code Online (Sandbox Code Playgroud)