VB Collection to C# Conversion

你说的曾经没有我的故事 提交于 2019-12-11 14:55:00

问题


I hope this makes sense.

I have a program that I am converting from a combination of VB6, and VB.Net 2 to C# 4.

I am having a problem with collections in VB, they are a KeyValuePair. I have three collections:

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

In C# I have converted the m_oCol(string, clsFeatureCollection) which contains clsFeature to a list because I need clsFeature to hold Features inserted in a particular order for accurate processing ie Keys could be 1, 3, 2, 4, 5.

The others I have converted to a dictionary but I am not sure this is correct, however I am not sure what else to use.

Should these all be dictionaries because I am currently getting a cast error when I access a collection that has all three collections in one collection.

I guess what I am asking is should these collections be all the same type? List? Dictionary? or something else? The key factor is the clsFeature must be inserted in a particular order, again ie Keys could be 1, 3, 2, 4, 5. It seems I can only get it in a list to hold the order

Any advice is appreciated

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:


You have a couple of different options.

  1. List<KeyValuePair<string, clsFeatureObjectCollection>>
    Use this if you need duplicate keys, fast lookup is not important O(n) and insert order need to be preserved.
  2. Dictionary<string, clsFeatureObjectCollection>
    Use this if keys are unique, you need fast lookup O(1) and order is irrelevant.
  3. SortedDictionary<string, clsFeatureObjectCollection>
    Use this if keys are unique, you need fast lookup O(log n) and the order of the items should follow the key. (Or any comparer you supply)
  4. SortedList<string, clsFeatureObjectCollection>
    Similar to SortedDictionary. See What's the difference between SortedList and SortedDictionary? for comparison.


来源:https://stackoverflow.com/questions/32253845/vb-collection-to-c-sharp-conversion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!