Search code examples
vb.netdebuggingsystem.reflection

How to use reflection to get keys from Microsoft.VisualBasic.Collection


I know that it is not possible to get keys (How to get the Key and Value from a Collection VB.Net) and it is better to use other classes. However I am debugging 10 years old code and I cannot change it.

In the Watch Window I see: enter image description here

So it seems to be possible to deal the collection as "List(of KeyValuePair)". Can I do it in code or is it only an internal translation.

I basically need to list all KEYs in a Collection.


Solution

  • VisualBasic.Collection has an undocumented private method InternalItemsList which allows reading keys besides values. The type of InternalItemsList is Microsoft.VisualBasic.Collection.FastList which does not seem to be Enumerable but has a method Item which returns items with a zero based index. The type of those items is Microsoft.VisualBasic.Collection.Node. An item has two private properties m_Value and m_Key. And here we are.

    Following code illustrates how to convert VisualBasic.Collection to List(Of KeyValuePair.

    Dim flg As BindingFlags = BindingFlags.Instance Or BindingFlags.NonPublic
    Dim InternalList As Object = col.GetType.GetMethod("InternalItemsList", flg).Invoke(col, Nothing)
    Dim res As New List(Of KeyValuePair(Of String, Object))
    For qq As Integer = 0 To col.Count - 1
        Dim Item As Object = InternalList.GetType.GetProperty("Item", flg).GetValue(InternalList, {qq})
        Dim Key As String = Item.GetType.GetField("m_Key", flg).GetValue(Item)
        Dim Value As Object = Item.GetType.GetField("m_Value", flg).GetValue(Item)
        res.Add(New KeyValuePair(Of String, Object)(Key, Value))
    Next
    

    I know that using undocumented functions is not safe but it is for internal use only and only solution I have managed to find.