【问题标题】:Serializing and Searching Object Collections序列化和搜索对象集合
【发布时间】:2014-09-16 22:32:39
【问题描述】:

如果有人能回答一些关于存储和搜索对象集合的问题,我将不胜感激。如果您能给出任何建议的基本示例,我将不胜感激。

存储:

我正在编写一个需要在 Active Directory 中搜索计算机对象的应用程序,并将它们存储在对象集合中。我想在下次运行应用程序时保存计算机对象集合以及未存储在 Active Directory 中的其他信息(例如计算机的 MAC 地址)。我还想保存 OU 的列表。

到目前为止,这是我的对象集合(它将具有更多属性)。保存收藏的最佳方法是什么?最好不使用数据库或保存到文件会对性能产生巨大影响?

或者有没有更好的方法来做我下面的事情?

Public Class Computer

    Public Property Name As String
    Public Property FQDN As String
    Public Property Path As String

End Class

Public Class ComputerCollection
    Inherits Collections.CollectionBase

    Public Sub Add(ByVal computer As Computer) 'Adds a new computer object to the collection
        List.Add(computer)
    End Sub

End Class

搜索:

我有一个类似于 ADUC 的布局,其中包含 OU 的树形视图和显示所选 OU 中计算机对象的列表视图。以下代码循环遍历计算机对象集合,检查计算机对象的路径是否与选定的 OU 路径匹配,然后将它们显示在列表视图中。

就性能而言,这是最好的方法吗?还是有更快的方法?

Private Sub tvOU_AfterSelect(sender As Object, e As TreeViewEventArgs) Handles tvOU.AfterSelect

    lvComputers.Items.Clear()

    If tvOU.SelectedNode.Name > "" Then

        For Each computerObj In computers

            If computerObj.Path.ToString.Replace("CN=" + computerObj.Name + ",", "") = tvOU.SelectedNode.Name Then
                Dim lvItem As New ListViewItem
                lvItem.Text = computerObj.Name
                lvComputers.Items.Add(lvItem)
            End If

        Next

    Else
        Exit Sub
    End If

End Sub

【问题讨论】:

  • 除非您使用的是 VB.NET 2002 或 2003,否则不要继承 CollectionBase。要么创建一个List(Of Computer),或者,如果你想要一个自定义集合,继承Collection(Of Computer)。
  • 你可以做的一个优化是在你的类中添加一个 CNName 属性,这样你就不必在循环中进行字符串混搭,只需迭代你的 List 或 Collection

标签: vb.net object collections


【解决方案1】:

一个简单的List(Of Computer) 确实是您所需要的,除非有其他未知的要求。对这种类型的东西使用序列化保存非常简单,对于List 或Collection<T> 也一样。

Imports System.Collections.ObjectModel

Public Class ComputersCollection
    Inherits Collection(Of Computer)
    ' NOT the crude thing in the VB NameSpace

    ' there is almost nothing to add: item, add and remove
    ' are in the base class
    ' ... perhaps saving and retrieving them by a key (name)
    ' which may do away with the search procedure in the posted code

End Class

Private Computers As New Collection(Of Computer)
' or
Private Computers As New List(Of Computer)

另一部分,保存您的收藏,可以通过序列化变得简单。首先,您必须将 Serializable 属性添加到您的 Computer 类中:

<Serializable>
Public Class Computer

如果您忘记了,则会收到错误 Class foobar is not marked as serializable。保存到磁盘:

Imports System.Runtime.Serialization

Private myComputerFile As String = ...

Dim bf As New BinaryFormatter
Using fs As New FileStream(myComputerFile , FileMode.OpenOrCreate)
    bf.Serialize(fs, Computers)
End Using

然后您可以轻松地重新创建列表或集合;这次的名单:

' ToDo: add a check to skip if file is not there
' as in the first time run
Dim bf As New BinaryFormatter
Using fs As New FileStream(myComputerFile , FileMode.Open)
    Computers = CType(bf.Deserialize(fs), List(Of Computers))
End Using

您也可以使用 XML 序列化程序来创建 XML 文件或使用更快、更智能的二进制序列化程序 ProtoBuf-Net

【讨论】:

  • 在序列化之前你不必序列化(将声明放在类的顶部)。我以为你确实告诉它这个类是序列化的?
  • @MrCoDeXeR 是的,它需要Attribute,他的课程不是答案的一部分,所以我忘记了。已添加,谢谢!
  • 非常感谢您的回复,我已经开始工作了 :)
猜你喜欢
  • 2020-02-24
  • 2010-11-30
  • 2019-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多