El uso es idéntico a una colección de tipo NameValueCollection (key:String, value:String) pero con la diferencia de que el valor es de tipo Object (key:String, value:Object).
Casos de uso: convertir un JSON donde el valor no es del tipo String.
Código
' *********************************************************************** ' Author : ElektroStudios ' Modified : 08-July-2023 ' *********************************************************************** #Region " Option Statements " Option Strict On Option Explicit On Option Infer Off #End Region #Region " Imports " Imports System.Collections.Specialized Imports System.Runtime.Serialization #End Region Namespace DevCase.Runtime.Collections ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Similarly to a <see cref="NameValueCollection"/>, this class represents a ''' collection of associated <see cref="String"/> keys and <see cref="Object"/> values ''' that can be accessed either with the name or with the index. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- <Serializable> Public Class NameObjectCollection : Inherits NameObjectCollectionBase #Region " Private MethFieldsods " ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Cached array of values in this <see cref="NameObjectCollection"/>. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- Private _all() As Object ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Cached array of keys in this <see cref="NameObjectCollection"/>. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- Private _allKeys() As String #End Region #Region " Properties " ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Gets or sets the entry with the specified key in this <see cref="NameObjectCollection"/>. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="name"> ''' The <see cref="String"/> key of the entry to locate. The key can be null. ''' </param> ''' ---------------------------------------------------------------------------------------------------- ''' <returns> ''' A <see cref="Object"/> that contains the comma-separated list of values associated with ''' the specified key, if found; otherwise, null. ''' </returns> ''' ---------------------------------------------------------------------------------------------------- Default Public Property Item(name As String) As Object Get Return Me.[Get](name) End Get Set(value As Object) Me.[Set](name, value) End Set End Property ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Gets the entry at the specified index of this <see cref="NameObjectCollection"/>. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="index"> ''' The zero-based index of the entry to locate in the collection. ''' </param> ''' ---------------------------------------------------------------------------------------------------- ''' <returns> ''' A <see cref="Object"/> that contains the comma-separated list of values at the specified ''' index of the collection. ''' </returns> ''' ---------------------------------------------------------------------------------------------------- Default Public ReadOnly Property Item(index As Integer) As Object Get Return Me.[Get](index) End Get End Property ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Gets all the keys in this <see cref="NameObjectCollection"/>. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <returns> ''' A <see cref="String"/> array that contains all the keys of this <see cref="NameObjectCollection"/>. ''' </returns> ''' ---------------------------------------------------------------------------------------------------- Public Overridable ReadOnly Property AllKeys() As String() Get If Me._allKeys Is Nothing Then Me._allKeys = Me.BaseGetAllKeys() End If Return Me._allKeys End Get End Property #End Region #Region " Constructors " ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Initializes a new instance of the <see cref="NameObjectCollection"/> ''' class that is empty, has the default initial capacity and uses the default case-insensitive ''' hash code provider and the default case-insensitive comparer. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- Public Sub New() End Sub ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Initializes a new instance of the <see cref="NameObjectCollection"/> ''' class that is empty, has the specified initial capacity and uses the specified ''' hash code provider and the specified comparer. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="hashProvider"> ''' The <see cref="System.Collections.IHashCodeProvider"/> that will supply the hash codes for ''' all keys in this <see cref="NameObjectCollection"/>. ''' </param> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="comparer"> ''' The <see cref="System.Collections.IComparer"/> to use to determine whether two keys are equal. ''' </param> ''' ---------------------------------------------------------------------------------------------------- <Obsolete("Please use NameObjectCollection(IEqualityComparer) instead.")> Public Sub New(hashProvider As IHashCodeProvider, comparer As IComparer) MyBase.New(hashProvider, comparer) End Sub ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Initializes a new instance of the <see cref="NameObjectCollection"/> ''' class that is empty, has the specified initial capacity and uses the default ''' case-insensitive hash code provider and the default case-insensitive comparer. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="capacity"> ''' The initial number of entries that this <see cref="NameObjectCollection"/> ''' can contain. ''' </param> ''' ---------------------------------------------------------------------------------------------------- Public Sub New(capacity As Integer) MyBase.New(capacity) End Sub ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Initializes a new instance of the <see cref="NameObjectCollection"/> ''' class that is empty, has the default initial capacity, and uses the specified ''' <see cref="System.Collections.IEqualityComparer"/> object. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="equalityComparer"> ''' The <see cref="System.Collections.IEqualityComparer"/> object to use to determine whether two ''' keys are equal and to generate hash codes for the keys in the collection. ''' </param> ''' ---------------------------------------------------------------------------------------------------- Public Sub New(equalityComparer As IEqualityComparer) MyBase.New(equalityComparer) End Sub ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Initializes a new instance of the <see cref="NameObjectCollection"/> ''' class that is empty, has the specified initial capacity, and uses the specified ''' <see cref="System.Collections.IEqualityComparer"/> object. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="capacity"> ''' The initial number of entries that this <see cref="NameObjectCollection"/> ''' object can contain. ''' </param> ''' ''' <param name="equalityComparer"> ''' The <see cref="System.Collections.IEqualityComparer"/> object to use to determine whether two ''' keys are equal and to generate hash codes for the keys in the collection. ''' </param> ''' ---------------------------------------------------------------------------------------------------- Public Sub New(capacity As Integer, equalityComparer As IEqualityComparer) MyBase.New(capacity, equalityComparer) End Sub ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Copies the entries from the specified <see cref="NameObjectCollection"/> ''' to a new <see cref="NameObjectCollection"/> with the specified ''' initial capacity or the same initial capacity as the number of entries copied, ''' whichever is greater, and using the default case-insensitive hash code provider ''' and the default case-insensitive comparer. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="capacity"> ''' The initial number of entries that this <see cref="NameObjectCollection"/> ''' can contain. ''' </param> ''' ''' <param name="col"> ''' this <see cref="NameObjectCollection"/> to copy to the new <see cref="NameObjectCollection"/> ''' instance. ''' </param> ''' ---------------------------------------------------------------------------------------------------- Public Sub New(capacity As Integer, col As NameObjectCollection) MyBase.New(capacity) If col Is Nothing Then Throw New ArgumentNullException(NameOf(col)) End If Me.Add(col) End Sub ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Initializes a new instance of the <see cref="NameObjectCollection"/> ''' class that is empty, has the specified initial capacity and uses the specified ''' hash code provider and the specified comparer. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="capacity"> ''' The initial number of entries that this <see cref="NameObjectCollection"/> ''' can contain. ''' </param> ''' ''' <param name="hashProvider"> ''' The <see cref="System.Collections.IHashCodeProvider"/> that will supply the hash codes for ''' all keys in this <see cref="NameObjectCollection"/>. ''' </param> ''' ''' <param name="comparer"> ''' The <see cref="System.Collections.IComparer"/> to use to determine whether two keys are equal. ''' </param> ''' ---------------------------------------------------------------------------------------------------- <Obsolete("Please use NameObjectCollection(Int32, IEqualityComparer) instead.")> Public Sub New(capacity As Integer, hashProvider As IHashCodeProvider, comparer As IComparer) MyBase.New(capacity, hashProvider, comparer) End Sub ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Initializes a new instance of the <see cref="NameObjectCollection"/> ''' class that is serializable and uses the specified <see cref="System.Runtime.Serialization.SerializationInfo"/> ''' and <see cref="System.Runtime.Serialization.StreamingContext"/>. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="info"> ''' A <see cref="System.Runtime.Serialization.SerializationInfo"/> object that contains the information ''' required to serialize the new <see cref="NameObjectCollection"/> ''' instance. ''' </param> ''' ''' <param name="context"> ''' A <see cref="System.Runtime.Serialization.StreamingContext"/> object that contains the source ''' and destination of the serialized stream associated with the new <see cref="NameObjectCollection"/> ''' instance. ''' </param> ''' ---------------------------------------------------------------------------------------------------- Protected Sub New(info As SerializationInfo, context As StreamingContext) MyBase.New(info, context) End Sub #End Region #Region " Public Methods " ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Copies the entries in the specified <see cref="NameObjectCollection"/> ''' to the current <see cref="NameObjectCollection"/>. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="c"> ''' this <see cref="NameObjectCollection"/> to copy to the current ''' <see cref="NameObjectCollection"/>. ''' </param> ''' ---------------------------------------------------------------------------------------------------- Public Sub Add(c As NameObjectCollection) If c Is Nothing Then Throw New ArgumentNullException(NameOf(c)) End If Me.InvalidateCachedArrays() Dim count As Integer = c.Count For i As Integer = 0 To count - 1 Dim key As String = c.GetKey(i) Dim values() As Object = c.GetValues(i) If values IsNot Nothing Then For j As Integer = 0 To values.Length - 1 Me.Add(key, values(j)) Next j Else Me.Add(key, Nothing) End If Next i End Sub ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Invalidates the cached arrays and removes all entries from this <see cref="NameObjectCollection"/>. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- Public Overridable Sub Clear() If MyBase.IsReadOnly Then Throw New NotSupportedException("CollectionReadOnly") End If Me.InvalidateCachedArrays() MyBase.BaseClear() End Sub ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Copies the entire <see cref="NameObjectCollection"/> to a compatible ''' one-dimensional <see cref="System.Array"/>, starting at the specified index of the target array. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="dest"> ''' The one-dimensional <see cref="System.Array"/> that is the destination of the elements copied ''' from <see cref="NameObjectCollection"/>. The <see cref="System.Array"/> must ''' have zero-based indexing. ''' </param> ''' ''' <param name="index"> ''' The zero-based index in dest at which copying begins. ''' </param> ''' ---------------------------------------------------------------------------------------------------- Public Sub CopyTo(dest As System.Array, index As Integer) If dest Is Nothing Then Throw New ArgumentNullException(NameOf(dest)) End If If dest.Rank <> 1 Then Throw New ArgumentException("Arg_MultiRank") End If If index < 0 Then Throw New ArgumentOutOfRangeException(NameOf(index), "IndexOutOfRange") End If Dim count As Integer = Me.Count If dest.Length - index < count Then Throw New ArgumentException("Arg_InsufficientSpace") End If If Me._all Is Nothing Then Dim array(count - 1) As Object For i As Integer = 0 To count - 1 array(i) = Me.[Get](i) dest.SetValue(array(i), i + index) Next i Me._all = array Else For j As Integer = 0 To count - 1 dest.SetValue(_all(j), j + index) Next j End If End Sub ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Gets a value indicating whether this <see cref="NameObjectCollection"/> ''' contains keys that are not null. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <returns> ''' true if this <see cref="NameObjectCollection"/> contains keys ''' that are not null; otherwise, false. ''' </returns> ''' ---------------------------------------------------------------------------------------------------- Public Function HasKeys() As Boolean Return Me.InternalHasKeys() End Function ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Adds an entry with the specified name and value to this <see cref="NameObjectCollection"/>. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="name"> ''' The <see cref="String"/> key of the entry to add. The key can be null. ''' </param> ''' ''' <param name="value"> ''' The <see cref="String"/> value of the entry to add. The value can be null. ''' </param> ''' ---------------------------------------------------------------------------------------------------- Public Overridable Sub Add(name As String, value As Object) If MyBase.IsReadOnly Then Throw New NotSupportedException("CollectionReadOnly") End If Me.InvalidateCachedArrays() Dim arrayList As ArrayList = DirectCast(MyBase.BaseGet(name), ArrayList) If arrayList Is Nothing Then arrayList = New ArrayList(1) If value IsNot Nothing Then arrayList.Add(value) End If MyBase.BaseAdd(name, arrayList) ElseIf value IsNot Nothing Then arrayList.Add(value) End If End Sub ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Gets the values associated with the specified key from this <see cref="NameObjectCollection"/> ''' combined into one comma-separated list. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="name"> ''' The <see cref="String"/> key of the entry that contains the values to get. The key can ''' be null. ''' </param> ''' ---------------------------------------------------------------------------------------------------- ''' <returns> ''' A <see cref="String"/> that contains a comma-separated list of the values associated ''' with the specified key from this <see cref="NameObjectCollection"/>, ''' if found; otherwise, null. ''' </returns> ''' ---------------------------------------------------------------------------------------------------- Public Overridable Function [Get](name As String) As Object Dim list As ArrayList = DirectCast(MyBase.BaseGet(name), ArrayList) Return NameObjectCollection.GetAsOneObject(list) End Function ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Gets the values associated with the specified key from this <see cref="NameObjectCollection"/>. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="name"> ''' The <see cref="String"/> key of the entry that contains the values to get. The key can ''' be null. ''' </param> ''' ---------------------------------------------------------------------------------------------------- ''' <returns> ''' A <see cref="Object"/> array that contains the values associated with the specified ''' key from this <see cref="NameObjectCollection"/>, if found; otherwise, ''' null. ''' </returns> ''' ---------------------------------------------------------------------------------------------------- Public Overridable Function GetValues(name As String) As Object() Dim list As ArrayList = DirectCast(MyBase.BaseGet(name), ArrayList) Return NameObjectCollection.GetAsObjectArray(list) End Function ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Sets the value of an entry in this <see cref="NameObjectCollection"/>. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="name"> ''' The <see cref="String"/> key of the entry to add the new value to. The key can be null. ''' </param> ''' ''' <param name="value"> ''' The <see cref="Object"/> that represents the new value to add to the specified entry. ''' The value can be null. ''' </param> ''' ---------------------------------------------------------------------------------------------------- Public Overridable Sub [Set](name As String, value As Object) If MyBase.IsReadOnly Then Throw New NotSupportedException("CollectionReadOnly") End If Me.InvalidateCachedArrays() Dim arrayList As New ArrayList(1) From {value} MyBase.BaseSet(name, arrayList) End Sub ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Removes the entries with the specified key from this <see cref="NameObjectCollection"/> ''' instance. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="name"> ''' The <see cref="String"/> key of the entry to remove. The key can be null. ''' </param> ''' ---------------------------------------------------------------------------------------------------- Public Overridable Sub Remove(name As String) Me.InvalidateCachedArrays() MyBase.BaseRemove(name) End Sub ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Gets the values at the specified index of this <see cref="NameObjectCollection"/> ''' combined into one comma-separated list. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="index"> ''' The zero-based index of the entry that contains the values to get from the collection. ''' </param> ''' ---------------------------------------------------------------------------------------------------- ''' <returns> ''' A <see cref="String"/> that contains a comma-separated list of the values at the specified ''' index of this <see cref="NameObjectCollection"/>, if found; otherwise, ''' null. ''' </returns> ''' ---------------------------------------------------------------------------------------------------- Public Overridable Function [Get](index As Integer) As Object Dim list As ArrayList = DirectCast(MyBase.BaseGet(index), ArrayList) Return NameObjectCollection.GetAsOneObject(list) End Function ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Gets the values at the specified index of this <see cref="NameObjectCollection"/>. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="index"> ''' The zero-based index of the entry that contains the values to get from the collection. ''' </param> ''' ---------------------------------------------------------------------------------------------------- ''' <returns> ''' A <see cref="String"/> array that contains the values at the specified index of the ''' <see cref="NameObjectCollection"/>, if found; otherwise, null. ''' </returns> ''' ---------------------------------------------------------------------------------------------------- Public Overridable Function GetValues(index As Integer) As Object() Dim list As ArrayList = DirectCast(MyBase.BaseGet(index), ArrayList) Return NameObjectCollection.GetAsObjectArray(list) End Function ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Gets the key at the specified index of this <see cref="NameObjectCollection"/>. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="index"> ''' The zero-based index of the key to get from the collection. ''' </param> ''' ---------------------------------------------------------------------------------------------------- ''' <returns> ''' A <see cref="String"/> that contains the key at the specified index of this <see cref="NameObjectCollection"/>, ''' if found; otherwise, null. ''' </returns> ''' ---------------------------------------------------------------------------------------------------- Public Overridable Function GetKey(index As Integer) As String Return MyBase.BaseGetKey(index) End Function #End Region #Region " Private Methods " ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Resets the cached arrays of the collection to null. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- Protected Sub InvalidateCachedArrays() Me._all = Nothing Me._allKeys = Nothing End Sub ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Gets a value indicating whether the <see cref="NameObjectCollection"/> has keys that are not null. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <returns> ''' <c>true</c> if the <see cref="NameObjectCollection"/> has keys that are not null; otherwise, <c>false</c>. ''' </returns> ''' ---------------------------------------------------------------------------------------------------- Friend Overridable Function InternalHasKeys() As Boolean Return MyBase.BaseHasKeys() End Function ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Converts an <see cref="ArrayList"/> to a single object. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="list"> ''' The <see cref="ArrayList"/> to convert. ''' </param> ''' ---------------------------------------------------------------------------------------------------- ''' <returns> ''' The converted object. If the <see cref="ArrayList"/> contains a single item, that item is returned. ''' If the <see cref="ArrayList"/> contains multiple items, ''' a <see cref="Collection"/> object is created with the items and returned. ''' If the <see cref="ArrayList"/> is empty or null, null is returned. ''' </returns> ''' ---------------------------------------------------------------------------------------------------- Private Shared Function GetAsOneObject(list As ArrayList) As Object Dim num As Integer = If(list?.Count, 0) If num = 1 Then Return list(0) End If If num > 1 Then For i As Integer = 1 To num - 1 Next i Return collection End If Return Nothing End Function ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Converts an <see cref="ArrayList"/> to an array of objects. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <param name="list"> ''' The <see cref="ArrayList"/> to convert. ''' </param> ''' ---------------------------------------------------------------------------------------------------- ''' <returns> ''' An array of objects containing the items from the <see cref="ArrayList"/>. ''' If the <see cref="ArrayList"/> is empty or null, null is returned. ''' </returns> ''' ---------------------------------------------------------------------------------------------------- Private Shared Function GetAsObjectArray(list As ArrayList) As Object() Dim num As Integer = If(list?.Count, 0) If num = 0 Then Return Nothing End If Dim array(num - 1) As Object list.CopyTo(0, array, 0, num) Return array End Function #End Region End Class End Namespace