创建一个无法在外部更改的List属性

Ala*_*n K 5 vb.net properties class generic-list

我的VB.NET项目中有一个公共类,它有一个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
Run Code Online (Sandbox Code Playgroud)

现在,这只是工作正常和花花公子.项目中mlst_ParameterNames直接访问该字段的任何类都可以根据需要对其进行修改,但是通过公共属性访问它的任何程序都可以将其修改为内容,但由于属性过程始终返回副本,因此无处可去.列表,而不是列表本身.

但是,当然,这带来了开销,这就是为什么我觉得它只是......好吧,在某种程度上看起来"错误",即使它有效.

参数列表永远不会很大.它最多只包含50个项目,但通常少于10个项目,所以我看不出这是一个性能杀手.然而,它当然让我认为有些人可以拥有更加整洁和清洁的想法.

任何人?

Ste*_*art 9

您应该使用该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
Run Code Online (Sandbox Code Playgroud)

根据MSDN:

该方法是O(1)操作.

这意味着AsReadOnly无论列表的大小如何,方法的速度都是相同的.

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

此外,该列表是真正的只读.它没有Add或没有Clear方法,因此使用该对象的其他人会更少混淆.

或者,如果您只需要让消费者能够遍历列表,那么您可以只公开属性IEnumerable(Of String)本身就是只读接口:

Public ReadOnly Property ParameterNames() As IEnumerable(Of String)
    Get
        Return mlst_ParameterNames
    End Get
End Property
Run Code Online (Sandbox Code Playgroud)

但是,这使得它仅在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
Run Code Online (Sandbox Code Playgroud)

  • 那是BRILLIANT,谢谢.这是一种高效的方式来获得我需要去的地方.我仍然主要在VBA工作,而且MS在很多方面越来越让我烦恼,我不禁对他们已经内置到.Net中的一些东西印象深刻.它让生活变得比VB6中那些笨重的老式系列容易得多.然而,如果没有知道如何以这种方式应用它们的人,这些特征本身就是无用的.再次感谢. (2认同)