2

全て、

VB.Netに変換したい約100のカスタムコレクションクラスを持つVB6プロジェクトがあります。典型的な例は次のようになります。

Class CAccounts
     Private m_Accounts As New Collection

     Public Sub Add(newItem As CAccount)
         m_Accounts.Add newItem, newItem.IdKey
     End Sub
     Public Sub Remove(index As Variant)
         m_Accounts.Remove index
     End Sub
     Public Function Item(index As Variant) As CAccount
         Set Item = Nothing
         On Error Resume Next
         Set Item = m_Accounts.Item(index)
     End Function

     .........

保存されているアイテムはどこにありますか

Class CAccount
    Public Id as long
    Public Code as String
    Public Name as string
    Public Sub Init(ByVal Id as Long)
        Me.Id = Id
        Code = ""
        Name = ""
    End Sub
    Public Property Get IdKey() as String
        IdKey = Code
    End Property

    ......

プロジェクト内のすべてのコレクションクラスは、この標準的なアプローチを使用します。ただし、コレクションクラスのすべてのプロパティ/メソッドが実際に使用されるわけではありません。コレクションのほとんどは、「foreach」ループで使用されます。文字列キーを使用したキーアクセスは非常に一般的です。インデックスによるキーアクセスはあまり一般的ではありません。

理想的には、これらのクラスを変換するための標準的なアプローチを採用したいと思います。各コレクションを確認する必要はなく、リストや辞書などが必要かどうかを検討するために使用します。これらのコレクションには100,000個のオブジェクトが含まれるものもあれば、10個しか含まれないものもあります。より単純なオプションで実行できる、より複雑な構造を使用してパフォーマンスの問題を引き起こしたくない。

最善のアプローチについてアドバイスをいただければ幸いです。私は次のことを考えました。

  1. 古いスタイルのコレクションにこだわる。したがって、VB.Netに変換するのは比較的簡単ですが、私はむしろより近代的な構造に移行したいと思います。

  2. CAccountsにKeyedCollection(Of String、CAccount)を継承させます。幸い、コレクションに保持されているほとんどのクラスには、クラスの一部としてキーがあります(たとえば、上記のCAccount.IdKey)。これはうまくいくようです。ただし、数値インデックスによるコレクションにアクセスするクラスは比較的少数です。それで、文字列キーによるキー付きアクセスのみが必要な場合、これはおそらくやり過ぎですか?

  3. 数値インデックスによるアクセスを必要としないクラスのCAccountsInheritDictionary(Of String、CAccount)を用意します。これに関して私が抱えている問題は、既存の「foreach」ループがすべて「アカウント内のアカウントごと」のようになっていることです。これらすべての発生を「accounts.Valuesのアカウントごとに」のようなものに変更する必要はありません。おそらく、デフォルトのプロパティを変更することでこれを回避できますか?

  4. CAccountsにMyCollection(Of String、CAccount)を継承させます。ここで、MyCollectionは私自身のオーダーメイドのコレクションです。これは少し大変な作業のようです。

私はオプション2に行く傾向があります-すべてをKeyedCollectionにします。次に、必要に応じて例外を作成します(たとえば、一意でないキー)。ただし、KeyedCollectionsがDictionariesよりもはるかに遅い場合は、Dictionaryを標準として使用し、数値インデックスによるアクセスが必要な場合はKeyedCollectionを使用します。

すべてのアドバイスに感謝します。

4

2 に答える 2

1
  • Dictionary(Of String, Whatever)すべてのコレクションをまたKeyedCollectionはのどちらか適切と思われる方に変換します。
  • プログラムを実行して、パフォーマンスの問題があるかどうかを確認します。
  • 存在する場合は、プロファイラーを使用して原因を特定し、そのタイプをより適切なものに変更します。

しかし、一般的には、VB6コードを移植しようとするのではなく、常に完全に書き直すことをお勧めします。私の経験では、そして他の開発者から聞いたことから、少なくとも積極的に開発されているコードでは、これは常により少ない時間を消費します。コードベースが二度と変更されないライトワンスポートがある場合は、移植の方が理にかなっているかもしれませんが、最新のコレクションを使用する必要はありません。互換性クラスを使用するだけです。

于 2012-04-21T12:50:53.427 に答える
0

KeyedCollection<TKey, TItem> ここでMSDNの記事が必要になります:http: //msdn.microsoft.com/en-us/library/ms132438.aspx

Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel

' This class represents a very simple keyed list of OrderItems,
' inheriting most of its behavior from the KeyedCollection and 
' Collection classes. The immediate base class is the constructed
' type KeyedCollection(Of Integer, OrderItem). When you inherit
' from KeyedCollection, the second generic type argument is the 
' type that you want to store in the collection -- in this case
' OrderItem. The first generic argument is the type that you want
' to use as a key. Its values must be calculated from OrderItem; 
' in this case it is the Integer field PartNumber, so SimpleOrder
' inherits KeyedCollection(Of Integer, OrderItem).
'
Public Class SimpleOrder
    Inherits KeyedCollection(Of Integer, OrderItem)

    ' The parameterless constructor of the base class creates a 
    ' KeyedCollection with an internal dictionary. For this code 
    ' example, no other constructors are exposed.
    '
    Public Sub New()
        MyBase.New()
    End Sub

    ' This is the only method that absolutely must be overridden,
    ' because without it the KeyedCollection cannot extract the
    ' keys from the items. The input parameter type is the 
    ' second generic type argument, in this case OrderItem, and 
    ' the return value type is the first generic type argument,
    ' in this case Integer.
    '
    Protected Overrides Function GetKeyForItem( _
        ByVal item As OrderItem) As Integer

        ' In this example, the key is the part number.
        Return item.PartNumber   
    End Function

End Class
于 2012-04-21T12:50:24.920 に答える