VB Коллекция для преобразования C#

Я надеюсь это имеет смысл.

У меня есть программа, которую я конвертирую из комбинации VB6 и VB.Net 2 в C# 4.

У меня проблема с коллекциями в VB, они KeyValuePair. У меня есть три коллекции:

m_oCol(string, clsFeatureObjectCollection) which contains clsFeatureObject<br />
m_oCol(string, clsFeatureObject) which contains clsFeatureCollection<br />
m_oCol(string, clsFeatureCollection) which contains clsFeature

В C# я преобразовал m_oCol(string, clsFeatureCollection), который содержит clsFeature, в список, потому что мне нужно, чтобы clsFeature содержал объекты, вставленные в определенном порядке для точной обработки, т.е. ключи могут быть 1, 3, 2, 4, 5.

Другие я перевел в словарь, но я не уверен, что это правильно, однако я не уверен, что еще использовать.

Должны ли они все быть словарями, потому что в настоящее время я получаю ошибку преобразования при доступе к коллекции, в которой все три коллекции находятся в одной коллекции.

Я думаю, что я спрашиваю, должны ли эти коллекции быть одного и того же типа? Список? Толковый словарь? или что-то другое? Ключевым фактором является то, что clsFeature должен быть вставлен в определенном порядке, то есть ключи могут быть 1, 3, 2, 4, 5. Кажется, я могу получить его только в списке, чтобы сохранить порядок

Любой совет приветствуется

clsFeatureCollection.vb

Option Strict Off
Option Explicit On

Imports ESRI.ArcGIS.esriSystem

Public Class clsFeature

Private m_OID As Integer
Private m_Geometry As ESRI.ArcGIS.Geometry.IGeometry

Public Sub New(ByRef iOID As Integer, ByRef pGeometry As ESRI.ArcGIS.Geometry.IGeometry)
    m_OID = iOID
    m_Geometry = pGeometry
End Sub

Public ReadOnly Property OID() As Integer
    Get
        OID = m_OID
    End Get
End Property

Public ReadOnly Property Geometry() As ESRI.ArcGIS.Geometry.IGeometry
    Get
        Geometry = m_Geometry
    End Get
End Property
End Class

Friend Class clsFeatureCollection
Implements System.Collections.IEnumerable

Private m_oCol As Collection
Private m_oColReverse As Collection

Public Sub New()
    MyBase.New()
    m_oCol = New Collection
    m_oColReverse = New Collection
End Sub

Public Sub Add(ByRef pFeature As ESRI.ArcGIS.Geodatabase.IFeature, Optional ByRef strBefore As String = "", Optional ByRef strAfter As String = "", Optional ByRef bReverse As Boolean = False)
    'Create a new cFoo object based on parameters
    'passed to this method, then add the new cFoo to 
    'the private collection, and key it by a
    'unique identifier built into cFoo
    'so we can retrieve it quickly later

    'Add the new foo object to the collection

    If bReverse Then
        m_oColReverse.Add(pFeature.OID.ToString().Trim(), pFeature.OID.ToString().Trim())
    End If

    If Not ContainsItem(pFeature.OID.ToString().Trim()) Then
        If strBefore <> "" Then
            m_oCol.Add(New clsFeature(pFeature.OID, pFeature.ShapeCopy), pFeature.OID.ToString().Trim(), strBefore)
        ElseIf strAfter <> "" Then
            m_oCol.Add(New clsFeature(pFeature.OID, pFeature.ShapeCopy), pFeature.OID.ToString().Trim())
        Else
            m_oCol.Add(New clsFeature(pFeature.OID, pFeature.ShapeCopy), pFeature.OID.ToString().Trim())
        End If
    End If

End Sub

Public Sub AddBefore(ByRef pFeature As ESRI.ArcGIS.Geodatabase.IFeature, ByRef strBefore As String, Optional ByRef bReverse As Boolean = False)
    'Create a new cFoo object based on parameters
    'passed to this method, then add the new cFoo to
    'the private collection, and key it by a
    'unique identifier built into cFoo
    'so we can retrieve it quickly later

    'Add the new foo object to the collection
    If bReverse Then
        m_oColReverse.Add(pFeature.OID.ToString().Trim(), pFeature.OID.ToString().Trim())
    End If

    If Not ContainsItem(pFeature.OID.ToString().Trim()) Then
        If strBefore <> "" Then
            m_oCol.Add(New clsFeature(pFeature.OID, pFeature.ShapeCopy), pFeature.OID.ToString().Trim(), strBefore)
        Else
            m_oCol.Add(New clsFeature(pFeature.OID, pFeature.ShapeCopy), pFeature.OID.ToString().Trim())
        End If
    End If

End Sub

Public Sub AddAfter(ByRef pFeature As ESRI.ArcGIS.Geodatabase.IFeature, ByRef strAfter As String, Optional ByRef bReverse As Boolean = False)
    'Create a new cFoo object based on parameters
    'passed to this method, then add the new cFoo to
    'the private collection, and key it by a
    'unique identifier built into cFoo
    'so we can retrieve it quickly later

    'Add the new foo object to the collection
    If bReverse Then
        m_oColReverse.Add(pFeature.OID.ToString().Trim(), pFeature.OID.ToString().Trim())
    End If

    If Not ContainsItem(pFeature.OID.ToString().Trim()) Then
        If strAfter <> "" Then
            m_oCol.Add(New clsFeature(pFeature.OID, pFeature.ShapeCopy), pFeature.OID.ToString().Trim(), , strAfter)
        Else
            m_oCol.Add(New clsFeature(pFeature.OID, pFeature.ShapeCopy), pFeature.OID.ToString().Trim())
        End If
    End If

End Sub

Public ReadOnly Property Count() As Short
    Get
        'Return the number of objects in m_oCol
        Count = m_oCol.Count()
    End Get
End Property

Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
    GetEnumerator = m_oCol.GetEnumerator
End Function

Public Sub Remove(ByRef vIndex As Object)
    'Remove the specified object. Note here
    'that this method will operate on either
    'the index of the object we want removed
    'or the key of the object we want removed
    m_oCol.Remove(vIndex)
End Sub

Public Function Item(ByRef vIndex As Object) As clsFeature
    'Retrieve the specified object. Note here
    'that this method will operate on either
    'the index of the object we want
    'or the key of the object we want
    Item = m_oCol.Item(vIndex)
End Function

Public Sub Clear()
    'remove all objects from the private collection
    m_oCol = New Collection
    m_oColReverse = New Collection
End Sub

Public Function Reverse(ByRef val_Renamed As Object) As Boolean
    Try
        If m_oColReverse.Contains(val_Renamed) Then
            Return True
        Else
            Return False
        End If
    Catch ex As Exception
        If TypeOf ex Is ArgumentException Or TypeOf ex Is IndexOutOfRangeException Then
            Reverse = False
        End If
    End Try
End Function

Public Function ContainsItem(ByRef val_Renamed As Object) As Boolean
    Try
        If m_oCol.Contains(val_Renamed) Then
            Return True
        Else
            Return False
        End If

    Catch ex As Exception
        If TypeOf ex Is ArgumentException Or TypeOf ex Is IndexOutOfRangeException Then
            ContainsItem = False
        End If
    End Try
End Function

Private Sub Class_Terminate_Renamed()
    'Set up the collection
    m_oCol = Nothing
    m_oColReverse = Nothing
End Sub

Protected Overrides Sub Finalize()
    Class_Terminate_Renamed()
    MyBase.Finalize()
End Sub
End Class

1 ответ

У вас есть несколько разных вариантов.

  1. List<KeyValuePair<string, clsFeatureObjectCollection>>
    Используйте это, если вам нужны дубликаты ключей, быстрый поиск не важен O(n) и порядок вставки должен быть сохранен.
  2. Dictionary<string, clsFeatureObjectCollection>
    Используйте это, если ключи уникальны, вам нужен быстрый поиск O(1), а порядок не имеет значения.
  3. SortedDictionary<string, clsFeatureObjectCollection>
    Используйте это, если ключи уникальны, вам нужен быстрый поиск O(log n) и порядок элементов должен следовать за ключом. (Или любой компаратор, который вы поставляете)
  4. SortedList<string, clsFeatureObjectCollection>
    Аналогично SortedDictionary. Смотрите В чем разница между SortedList и SortedDictionary? для сравнения.
Другие вопросы по тегам