vb.net - 创建一个不能从外部更改的 List 属性

标签 vb.net class properties generic-list

我的 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 方法的速度都是相同的。

除了潜在的性能优势之外,列表的只读版本会自动与原始列表保持同步,因此如果使用代码保留对其的引用,其引用的列表仍将是最新的,即使稍后将项目添加到列表中或从列表中删除。

此外,该列表实际上是只读的。它没有 AddClear 方法,因此使用该对象的其他人不会感到困惑。

或者,如果您所需要的只是让使用者能够迭代列表,那么您可以将该属性公开为 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/

相关文章:

mysql - 如何通过在mysql中过滤另一个表来列出表中的所有项目

java - 指纹扫描仪

mysql - 日期数据类型的 fatal error : MySQL Insert from VB.

c# - 为什么 C# 对内部 KeyValuePairs 使用结构而不是类

class - Coq:定义类型类实例

java - Android:为敌人创建存储阵列

ios - kABPerson 属性 |知道地址簿联系人是否也在使用 iPhone?

swift - 如何使用属性观察者提供的定制?

.net - 将控制台颜色转换为颜色?

c# - C#类的属性包