奇怪的VB.NET数组属性情况

时间:2009-12-27 12:46:51

标签: vb.net arrays class properties

我有这种奇怪的情况。

我有这两个类:

Public Class Entry

End Class

Public Class Core

End Class

Core类的一个属性是Entry对象数组。我怎么声明呢?

现在,从外部更改(添加/删除)此数组的唯一方法应该是使用两个函数 - AddEntry(Ent As Entry)和RemoveEntry(ID As String)。请注意,在这里,任何调用AddEntry函数的人都应该只是创建一个Entry对象并传递它。它将被添加到现有数组中。

但是,Entry数组应该可以从外部访问,用于循环和打印或类似的东西:

' core1 is a valid Core object
For Each Ent As Entry In core1.Entries
  MsgBox(Ent.SomeProperty)
Next Ent

是否可以将Array公开为属性,但仅限于通过函数进行修改?我知道Add和Remove函数中的逻辑可以在setter或getter中,但想要添加的人应该只传递一个Entry对象。

就像说你只能访问数组,但是为了修改它,只需创建一个对象并发送它或ID来删除它。不要打扰整个阵列。

我希望我有意义。

3 个答案:

答案 0 :(得分:1)

为什么要将其公开为数组?

我会做的是在内部使用List来存储条目。 (该列表将是私人的) 创建必要的公共方法(AddEntry / RemoveEntry / ...),它们操纵私有列表。

然后,创建一个暴露List的公共属性,但是以ReadOnly方式。也就是说,该属性应该返回一个ReadOnlyCollection实例。 像这样:

(我知道它在C#中,但这是我的'主要语言' - 将它转换为VB.NET有点懒得)

public class Core
{
    private List<Entry> _entries = new List<Entry>();

    public void AddEntry( Entry entry )
    {
        _entries.Add (entry);
    }

    public ReadOnlyCollection<Entry> Entries
    {
       get { return _entries.AsReadOnly(); }
    }
}

编辑 MarkJ提供的VB.Net版

Imports System.Collections.ObjectModel 
Public Class Core 
  Private _entries As New List(Of Entry) 

  Public Sub AddEntry( new As Entry ) 
    _entries.Add (new) 
  End Sub 

  Public ReadOnly Property Entries() As ReadOnlyCollection(Of Entry) 
    Get 
      Return _entries.AsReadOnly 
    End Get 
  End Property 
End Class 

答案 1 :(得分:0)

为数组创建一个私有字段,然后创建访问方法以在内部使用该数组。为了将此数组公开给调用者以便他们可以枚举它,您应该公开类型为IEnumerable(Of T)的属性。

这种方法并非万无一失,但是,聪明的调用者可以简单地将IEnumerable(Of T)强制转换回数组并对其进行修改,因此可能需要创建数组的副本并返回 作为IEnumerable(Of T)。所有这些都有明显的性能损失,因为我相信你已经看到了。这只是将数组用作底层数据结构时可能出现的众多问题之一。

答案 2 :(得分:0)

您可以将List保持为私有,而是返回IEnumerable。通过Reflector生成的代码 - 我希望它是可读的:

Public Class Core
    Public Sub AddEntry(ByVal Ent As Entry)
        Me.entries.Add(Ent)
    End Sub

    Public Sub RemoveEntry(ByVal ID As String)
        Dim pred As Predicate(Of Entry) = Function (ByVal entry As Entry) 
            Return (entry.Id = ID)
        End Function
        Me.entries.RemoveAll(pred)
    End Sub

    Public ReadOnly Property Entries As IEnumerable(Of Entry)
        Get
            Return Me.entries
        End Get
    End Property

    Private entries As List(Of Entry) = New List(Of Entry)
End Class

注意:如果您要添加和删除对象,我建议使用List<Entry>而不是数组 - 或者根据您使用它的方式甚至使用Dictionary<string, Entry>