【问题标题】:Are set-only properties bad practice? [duplicate]仅设置属性是不好的做法吗? [复制]
【发布时间】:2010-12-30 17:50:17
【问题描述】:

我有一些 C# 代码喜欢创建具有 setter 但没有 getter 的属性。对我来说,这似乎是一种反模式,但我是否遗漏了什么?

public List<SiteVisitSummary> DataSource {
    set {
        // crazy logic here 
    }
}

【问题讨论】:

  • 这是一个应该是方法的属性。

标签: c# anti-patterns


【解决方案1】:

我不知道我是否称它为反模式。我认为要意识到的重要一点是,您示例中的属性本质上是一个方法,伪装成一个属性。出于这个原因,它是不直观的,我通常会避免它。对我来说,这看起来更自然:

public void SetDataSource(IEnumerable<SiteVisitSummary> dataSource)
{
    // crazy logic here
}

我看到的一个相当合理的情况是,当有几个属性组合在一起时,将所有属性设置为单个值是合理的做法(但显然,getting全部作为一个值没有意义)。例如:

class Polyhedron
{
    public int Height { get; set; }
    public int Width { get; set; }
    public int Depth { get; set; }

    public int AllDimensions
    {
        set { Height = Width = Depth = value; }
    }
}

【讨论】:

  • 那么,如果它不直观且通常无用,那不就是反模式吗?
  • @kelloti:我可以同意一般没用;但我确实举了一个例子,我认为这是有道理的。所以我不会笼统地声明它在所有情况下都是反模式。
  • +1 为例,但我不同意这应该是一个属性。即使在这种情况下,它作为属性也没有任何意义。
  • 我认为作为属性比作为方法更有意义;您可以通过这种方式在对象初始化器列表中使用它。
  • 那么新多面体 { Width = 10, AllDimensions = 5 } 的行为是什么?此外,我希望 Height 和 Depth 以其自己的默认值初始化,实际上并非如此。我不喜欢代码不符合预期。
【解决方案2】:

这对于Dependency Injection 可能很有用,在这种情况下,您使用属性而不是使用构造函数进行注入。

【讨论】:

  • 我不明白你的意思,你能澄清一下吗?另外 - 它不用于 DI
  • @kelloti 添加了对 DI 的引用
  • 我知道 DI 是什么,但我想不出一种简单的方法来使用 DI 的仅设置属性
  • @kelloti 我能收集到的唯一原因是您在实例化时没有参考,并且不能使用构造函数进行注入,并且希望将其注入下游以进行测试可能...属性本身将只使用一个 setter 保持原样,因为 getter 没有直接价值,因为您只是尝试为对象播种...
  • 很公平,我想这可能有效
【解决方案3】:

我认为这种做法本身并没有什么不好的地方,尽管它对我来说没有多大意义。

封装的意义在于限制可以改变对象状态的因素,从而使状态变得更易于维护。我想不出任何充分的理由将属性设为只写。而且,如果可以的话,将其作为一种方法可能更有意义。

用户习惯于能够读取属性,他们可能会浪费时间想知道为什么您的属性如此奇怪。

【讨论】:

    【解决方案4】:

    如果您期望发生很多逻辑,那么通过使用一种方法来设置它似乎更清楚成本。

    【讨论】:

      【解决方案5】:

      这可能不是每个人都喜欢的,但我posted an answer to another question 演示了“注入器”概念的使用,在本例中是嵌套在不可变结构中的结构。 infuser 具有只写属性,补充了不可变类型的只读属性。

      公平地说,我同意这种方法可能会造成混淆,在将这样的代码包含在不仅仅是一个业余项目的应用程序中之前,我会三思而后行。

      这个概念对于普通类也很有用,而不仅仅是不可变类型。它允许负责实例化对象的代码对该对象中包含的数据进行读/写访问。然后可以将该对象传递给其他代码,该代码对对象内的数据具有只读访问权限。

      【讨论】:

      • 我想添加一个约束,即使用仅设置属性应该是一个非笨拙的理由
      • 嗯。好吧,正如我所说,这不是每个人的一杯茶。不过,我真的不认为这是一个杂牌。我认为它是一种可能的设计选择来控制哪些代码对对象具有写访问权。仅设置属性是实现此类设计选择的一种可能方式。
      【解决方案6】:

      这样的做法还不错,只是不是很有用(您看不懂的属性?)。

      【讨论】:

      • 如果某样东西没有用处,那不就是一种不好的做法吗?
      • @Gabe - 我将bad practice 类为harmful。这无害。
      【解决方案7】:

      这真的是一件很奇怪的事情。你为什么要编写一个允许用户设置列表但不读取它的 API?如何改为返回 ReadOnlyCollection 并将属性公开为 IList 而不是 List?

      【讨论】:

      • 这让我想起了DataRow.ItemArray 属性,它的类型为object[] 并且(令人惊讶的是)有一个setter。这很令人困惑,因为调用 ItemArray[0] = 5 什么都不做;该属性实际上是两种方法(一种将内部内容复制到数组中,另一种将输入数组复制回内部内容)。在这种情况下,我可以想象有一个只接受集合的方法可能是有意义的。
      • 是的,但在这种情况下,分配将是编译错误。当然,ReadOnlyCollection 不会通过更改存储在其中的对象的 properties 来修改某人。
      猜你喜欢
      • 2016-09-19
      • 2012-08-06
      • 2017-01-09
      • 2017-06-01
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 2011-04-10
      • 2021-10-27
      相关资源
      最近更新 更多