我的 VB.NET 项目中有一个公共(public)类,它有一个 List(Of String)
属性。该列表需要由项目内的其他类修改,但由于该类可能(在将来的某个时间)暴露在项目之外,因此我希望它在该级别上不可修改。项目中现有属性的修改只能通过调用列表的方法(特别是 .Add
,偶尔是 .Clear
)来完成,而不是通过批量替换该属性来完成值与新列表(这就是为什么我将其作为 ReadOnly
属性)。
我想出了一种的做法,但我不确定这是否正是您所谓的“优雅”。
是这样的:
Friend mlst_ParameterNames As List(Of String) = New List(Of String)
Public ReadOnly Property ParameterNames() As List(Of String)
Get
Return New List(Of String)(mlst_ParameterNames)
End Get
End Property
现在效果很好。项目中直接访问 mlst_ParameterNames
字段的任何类都可以根据需要对其进行修改,但是任何通过公共(public)属性访问它的过程都可以将其修改为自己想要的内容,但自此之后将一事无成。属性过程始终返回列表的副本,而不是列表本身。
但是,当然,这会带来开销,这就是为什么我觉得它只是......好吧,在某种程度上本能地“错误”,即使它有效。
参数列表永远不会很大。它最多只包含 50 个项目,但更常见的是少于 10 个项目,所以我不认为这会成为性能 killer 。然而,这当然让我想到,拥有更多 VB.NET 时间的人可能有一个更简洁的想法。
有人吗?
最佳答案
您应该使用 AsReadOnly
方法来获取列表的只读版本,而不是创建原始列表的新副本,如下所示:
Friend mlst_ParameterNames As List(Of String) = New List(Of String)
Public ReadOnly Property ParameterNames() As ReadOnlyCollection(Of String)
Get
Return mlst_ParameterNames.AsReadOnly()
End Get
End Property
根据MSDN :
This method is an O(1) operation.
这意味着,无论列表大小如何,AsReadOnly
方法的速度都是相同的。
除了潜在的性能优势之外,列表的只读版本会自动与原始列表保持同步,因此如果使用代码保留对其的引用,其引用的列表仍将是最新的,即使稍后将项目添加到列表中或从列表中删除。
此外,该列表实际上是只读的。它没有 Add
或 Clear
方法,因此使用该对象的其他人不会感到困惑。
或者,如果您所需要的只是让使用者能够迭代列表,那么您可以将该属性公开为 IEnumerable(Of String)
,它本质上是一个只读属性接口(interface):
Public ReadOnly Property ParameterNames() As IEnumerable(Of String)
Get
Return mlst_ParameterNames
End Get
End Property
但是,这使得只有在 For Each
循环中访问列表才有用。例如,您无法获取Count
或通过索引访问列表中的项目。
作为旁注,我建议添加第二个 Friend
属性,而不是简单地将字段本身公开为 Friend
。例如:
Private _parameterNames As New List(Of String)()
Public ReadOnly Property ParameterNames() As ReadOnlyCollection(Of String)
Get
Return _parameterNames.AsReadOnly()
End Get
End Property
Friend ReadOnly Property WritableParameterNames() As List(Of String)
Get
Return _parameterNames
End Get
End Property
关于vb.net - 创建一个不能从外部更改的 List 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16935257/