【问题标题】:Best way to expose an object with read-only properties only仅公开具有只读属性的对象的最佳方法
【发布时间】:2013-08-15 12:18:44
【问题描述】:

我的问题找不到答案,所以我要问一个新问题。

我有一个对象,我想从同一解决方案中的另一个类填充它的属性。但是对象应该只公开只读属性,这样外部调用者就不能看到也不能访问 setter(因为没有 setter)。

从同一解决方案中填充内部支持变量的最佳方法是什么?我知道我可以在构造函数中做到这一点,但我希望能够在创建对象后设置变量。

对不起,我的解释很奇怪,也许一些代码会有所帮助。

这就是我现在正在做的事情:

Public Class ReadonlyObject

    Protected Friend Sub New()
    End Sub

    'Could use this, but don't want to...
    Protected Friend Sub New(foo As String)
    End Sub

    Friend _foo As String

    Public ReadOnly Property Foo As String
        Get
            Return _foo
        End Get
    End Property

End Class

Public Class FillReadonlyObject

    Private Sub DoSomeHeavyWork()
        Dim roObject As New ReadonlyObject

        roObject._foo = "bar"

        'Could use this, but don't want to...want to access properties directly.
        Dim roObject2 As New ReadonlyObject("bar")

    End Sub

End Class

这样,ReadonlyObject 的属性被正确地公开为只读,但恐怕这是不好的做法。

我见过这样的实现:

Public Class ReadonlyObject

Protected Friend Sub New()
End Sub

Private _foo As String

Public Property Foo As String
    Get
        Return _foo
    End Get
    Friend Set(value As String)
        _foo = value
    End Set
End Property

End Class

Public Class FillReadonlyObject

Private Sub DoSomeHeavyWork()
    Dim roObject As New ReadonlyObject

    roObject.Foo = "bar"
End Sub

End Class

这可行,但使用 setter 公开属性。它不可访问,但它是可见的,我不希望这样:)

所以也许这只是一个装饰性的东西,但我认为告诉调用者(或至少是智能感知)该属性是严格只读的。

谢谢,杨

【问题讨论】:

  • 我想到的唯一问题是:为什么?你想改变一个属性的值,有三种解决方案:a)构造函数或任何其他方法将属性值作为参数,b)属性有setter或c)你改变属性后面的成员变量,在这种情况下首先,拥有一个属性没有意义。
  • 那么用 Private setter 代替 Friend 怎么样?
  • 他不能设置项目中其他类的属性。
  • 是的。他需要通过 Friend/Public 方法或构造函数来设置它。
  • 我看不出Public Get/Friend Set 方法有什么问题。这是最简单的,也是最干净的。

标签: vb.net properties accessor


【解决方案1】:

如果您想显式声明该属性为只读,但在构建后仍有办法设置它,那么您需要做的就是创建自己的 setter 方法,而不是使用自动为你可是财产。例如:

Public Class ReadonlyObject
    Protected Friend Sub New()
    End Sub

    Private _foo As String

    Public ReadOnly Property Foo As String
        Get
            Return _foo
        End Get
    End Property

    Friend Sub SetFoo(value As String)
        _foo = value
    End Sub
End Class

Public Class FillReadonlyObject
    Private Sub DoSomeHeavyWork()
        Dim roObject As New ReadonlyObject
        roObject.SetFoo("bar")
    End Sub
End Class

或者,您可以创建两个属性,如下所示:

Public Class ReadonlyObject
    Protected Friend Sub New()
    End Sub

    Public ReadOnly Property Foo As String
        Get
            Return HiddenFoo
        End Get
    End Property

    Friend Property HiddenFoo As String
End Class

Public Class FillReadonlyObject
    Private Sub DoSomeHeavyWork()
        Dim roObject As New ReadonlyObject
        roObject.HiddenFoo = "bar"
    End Sub
End Class

【讨论】:

  • 当然可以,但为什么不将支持变量声明为朋友并直接访问它呢?这是这么糟糕的行为吗?
  • @Jan 如果你这样做,那么如果你可以绕过它,为什么首先要有 readonly 属性?
  • @DouglasBarbin 我可以想到很多“唯一的原因是让属性在程序集之外只读”的情况就足够了。
  • 如果他担心需要输入的数量,他会选择一种最糟糕的语言来完成这项工作。
  • MSIL 本身并不支持属性。 这不是真的。 MSIL/CIL 完全了解属性,它们是使用.property 指令声明的。
猜你喜欢
  • 2010-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-22
  • 1970-01-01
  • 2015-05-14
  • 1970-01-01
相关资源
最近更新 更多