【问题标题】:Why static automatic properties is only useful in which the getter is public and setter is private为什么静态自动属性仅在 getter 为 public 而 setter 为 private 时才有用
【发布时间】:2013-05-24 08:44:24
【问题描述】:

在c# in depth>>一书中,我读过一句话“我可以看到静态自动属性有用的唯一场景是getter是公共的而setter是私有的,并且设置器仅在类型初始化程序中被调用”。我不确定 Jon skeet 在这里建议什么。

在我看来,getter 和 setter 都可以用作私有或公共。

【问题讨论】:

  • 整句话是什么?直接问他可能会好运。
  • 首先想到的是线程安全。如果您有一个公共静态 自动 属性设置器,那么您可以轻松创建竞争条件,因为该设置器在所有类实例之间共享。
  • @JohnWillemse 这句话只是声称静态自动属性的场景。我知道我们需要额外的工作来使 setter 线程安全,这不应该只应用于静态自动属性。
  • @ValidfroM,如果您从代码中的不同位置访问此属性(这是静态属性的常见场景),您会怎么做?您将如何在不同的类之间共享_lock 字段以同步访问?
  • 一个好的谷歌查询是“全局变量是邪恶的”。

标签: c# static automatic-properties


【解决方案1】:

关键是静态成员通常应该是线程安全的......并且自动实现的属性不是线程安全的,就任何保证一个线程写入的值而言立即被另一个人看到。您无法在自动属性中更改它,因此静态自动属性唯一有用的时候是:

  • 如果您不关心线程安全
  • 如果 setter 是私有的并且只能从静态初始化器设置(它是自动线程安全的)。在这种情况下,我通常只有一个只读静态变量和一个 getter-only 属性来公开它。

老实说,即使没有线程安全方面,可设置的静态属性一开始也很不寻常(在精心设计的代码中)。

【讨论】:

    【解决方案2】:

    因为自动属性打破了encapsulation,这是 OOP 的基本原则。您不能使用自动属性封装数据。封装的工作是确保您的对象保持一致的状态。如果您使用这样的自动属性:

    public IFoo Foo { get; set; }
    

    您无法验证 setter 中的值。将属性设置为null 是可能的,您甚至没有机会注意到或禁止它。这可能是你想要的,但它可能会让你更容易错误地使用你的界面。这就是为什么前面提到的blog-post 状态

    这是一种代码味道,而不是反模式。

    你应该更喜欢这种风格:

    public IFoo Foo { get; private set; } 
    

    因为这样你就有可能将你的引用与构造函数一起注入。

    public Bar(IFoo foo)
    {
        if (foo == null) 
            throw new ArgumentNullException("Foo");
    
        this.Foo = foo;
    }
    

    这使客户更容易以正确的方式使用您的对象。我真的建议阅读前面提到的blog-post。它很好地描述了为什么您应该更喜欢将 setter 保密。

    【讨论】:

    • 这句话是关于静态自动属性的。您的示例是关于正常的自动属性。不过我同意你的论点。
    • 静态类和非静态类的问题是一样的。在这种情况下,static 仅将类的实例数限制为 1。然而,这使得控制数据的设置方式通常变得更加重要。
    猜你喜欢
    • 1970-01-01
    • 2014-09-05
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 2014-05-10
    相关资源
    最近更新 更多