-
Jul 6th, 2015, 09:40 AM
#1
Thread Starter
New Member
[RESOLVED] Collection-like solution with both strong typing and keys
I'm trying to find a suitable solution for a collection of objects I have in Visual Basic. I would like the solution to have two properties:
- Strong typing
- Key-based access (in addition to index-based access)
So far I've been able to find structures that have one or the other. For example, List supports strong typing in its declaration but does not allow element access by key. Meanwhile, Collection elements are key-able but not strongly typed. What is the ideal solution here?
Thanks!
-
Jul 6th, 2015, 10:26 AM
#2
Re: Collection-like solution with both strong typing and keys
If you want access by key and by index then you can create an object which encapsulates both a list and a dictionary.
Or, you can use a System.Collections.Specialized.OrderedDictionary. Sounds like it'll do the job.
"Ok, my response to that is pending a Google search" - Bucky Katt.
"There are two types of people in the world: Those who can extrapolate from incomplete data sets." - Unk.
"Before you can 'think outside the box' you need to understand where the box is."
-
Jul 6th, 2015, 10:57 AM
#3
Thread Starter
New Member
Re: Collection-like solution with both strong typing and keys
Originally Posted by SJWhiteley
Well, I can definitely find a structure that allows access by both key and index (even a simple Collection does this). The issue I'm having is that those types, as far as I've seen, do not support strong typing. The OrderedDictionary, for example, doesn't take in an object type when it is initialized (as arrays and Lists do), so there's no way (that I'm aware of) to check that only objects of a particular type can be inside at compile time.
-
Jul 6th, 2015, 11:18 AM
#4
Re: Collection-like solution with both strong typing and keys
Well, if the OrderedDictionary (I had thought that it did) doesn't have strong typing, then just create an object encapsulating a List and Dictionary, and add methods to get items by index or key, as appropriate.
Edit: it also sounds like you may be talking about the specific Microsoft.Visualbasic.Collection object, rather than the strongly typed, generic, collections available in the .NET framework: you should never be using that for anything.
Last edited by SJWhiteley; Jul 6th, 2015 at 11:23 AM.
"Ok, my response to that is pending a Google search" - Bucky Katt.
"There are two types of people in the world: Those who can extrapolate from incomplete data sets." - Unk.
"Before you can 'think outside the box' you need to understand where the box is."
-
Jul 6th, 2015, 11:19 AM
#5
Re: Collection-like solution with both strong typing and keys
Hunh, I had never heard of an OrderedDictionary. That one doesn't appear to be strongly typed, but the Dictionary is, as is the SortedDictionary:
https://msdn.microsoft.com/en-us/lib...v=vs.110).aspx
You can also use indexes with Dictionaries, so you don't need both a list and dictionary to get all your requirements met.
My usual boring signature: Nothing
-
Jul 6th, 2015, 11:30 AM
#6
Re: Collection-like solution with both strong typing and keys
SortedDictionary sorts on the key, which may or may not provide the 'index' you want. I had presumed that an index-based collection would be indexed by the order they are added to the collection. Something that the SortedDictionary and Dictionary do not do.
(While you can use an iterator or an extension method on a dictionary, I'm not sure that it will give you the order that items are added).
"Ok, my response to that is pending a Google search" - Bucky Katt.
"There are two types of people in the world: Those who can extrapolate from incomplete data sets." - Unk.
"Before you can 'think outside the box' you need to understand where the box is."
-
Jul 6th, 2015, 11:36 AM
#7
Re: Collection-like solution with both strong typing and keys
well, it seems you get one or the other.... strongly typed objects, OR you get key/index access... I was able to get this working:
Code:
Dim openWith As New Dictionary(Of String, String)
' Add some elements to the dictionary. There are no
' duplicate keys, but some of the values are duplicates.
openWith.Add("txt", "notepad.exe")
openWith.Add("bmp", "paint.exe")
openWith.Add("dib", "paint.exe")
openWith.Add("rtf", "wordpad.exe")
MessageBox.Show(openWith.Item(openWith.Keys(1)))
The index is passed to the Keys collection, which then returns the key for that index, which is then passed to the Item collection and returns the value - "paint.exe" in this case.
You could probably roll your own class that acts like a Dictionary but overloads the Items property to accept a Key (as String) or an Index (as Integer).
-tg
-
Jul 6th, 2015, 11:39 AM
#8
Thread Starter
New Member
Re: Collection-like solution with both strong typing and keys
Originally Posted by SJWhiteley
SortedDictionary sorts on the key, which may or may not provide the 'index' you want. I had presumed that an index-based collection would be indexed by the order they are added to the collection. Something that the SortedDictionary and Dictionary do not do.
(While you can use an iterator or an extension method on a dictionary, I'm not sure that it will give you the order that items are added).
I initially thought that a SortedDictionary would do the trick, but you're correct in that the indexing order is not what I want. For now, I'll take your suggestion and create my own solution. I'd still love to hear about any built-in types that support what I'm trying to accomplish--it seems like one should exist, unless my need is a lot more specific than I imagine it to be. If no more suggestions crop up within a few hours, I'll mark this thread as resolved. Thanks!
-
Jul 6th, 2015, 11:50 AM
#9
Re: Collection-like solution with both strong typing and keys
Here's something to help you get started with.... I implemented the IDictionary(Of) interface... made some modifications where needed.
Code:
Public Class CustomKeyIndex(Of TKey, TValue)
Implements IDictionary(Of TKey, TValue)
Private _internalDictionary As New Dictionary(Of TKey, TValue)
Private _isreadOnly As Boolean = False
Public Sub Add(item As KeyValuePair(Of TKey, TValue)) Implements ICollection(Of KeyValuePair(Of TKey, TValue)).Add
_internalDictionary.Add(item.Key, item.Value)
End Sub
Public Sub Clear() Implements ICollection(Of KeyValuePair(Of TKey, TValue)).Clear
_internalDictionary.Clear()
End Sub
Public Function Contains(item As KeyValuePair(Of TKey, TValue)) As Boolean Implements ICollection(Of KeyValuePair(Of TKey, TValue)).Contains
Return _internalDictionary.Contains(item)
End Function
Public Sub CopyTo(array() As KeyValuePair(Of TKey, TValue), arrayIndex As Integer) Implements ICollection(Of KeyValuePair(Of TKey, TValue)).CopyTo
array = _internalDictionary.ToArray
End Sub
Public ReadOnly Property Count As Integer Implements ICollection(Of KeyValuePair(Of TKey, TValue)).Count
Get
Return _internalDictionary.Count
End Get
End Property
Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of KeyValuePair(Of TKey, TValue)).IsReadOnly
Get
Return _isreadOnly
End Get
End Property
Public Function Remove(item As KeyValuePair(Of TKey, TValue)) As Boolean Implements ICollection(Of KeyValuePair(Of TKey, TValue)).Remove
_internalDictionary.Remove(item.Key)
End Function
Public Sub Add(key As TKey, value As TValue) Implements IDictionary(Of TKey, TValue).Add
_internalDictionary.Add(key, value)
End Sub
Public Function ContainsKey(key As TKey) As Boolean Implements IDictionary(Of TKey, TValue).ContainsKey
Return _internalDictionary.ContainsKey(key)
End Function
Default Public Property Item(key As TKey) As TValue Implements IDictionary(Of TKey, TValue).Item
Get
Return _internalDictionary(key)
End Get
Set(value As TValue)
_internalDictionary(key) = value
End Set
End Property
Default Public Property Item(index As Integer) As TValue
Get
Return _internalDictionary(_internalDictionary.Keys(index))
End Get
Set(value As TValue)
_internalDictionary(_internalDictionary.Keys(index)) = value
End Set
End Property
Public ReadOnly Property Keys As ICollection(Of TKey) Implements IDictionary(Of TKey, TValue).Keys
Get
Return _internalDictionary.Keys
End Get
End Property
Public Function Remove1(key As TKey) As Boolean Implements IDictionary(Of TKey, TValue).Remove
_internalDictionary.Remove(key)
End Function
Public Function TryGetValue(key As TKey, ByRef value As TValue) As Boolean Implements IDictionary(Of TKey, TValue).TryGetValue
Dim retValue As Boolean = False
If _internalDictionary.Keys.Contains(key) Then
value = _internalDictionary.Item(key)
retValue = True
End If
Return retValue
End Function
Public ReadOnly Property Values As ICollection(Of TValue) Implements IDictionary(Of TKey, TValue).Values
Get
Return _internalDictionary.Values
End Get
End Property
Public Function GetEnumerator() As IEnumerator(Of KeyValuePair(Of TKey, TValue)) Implements IEnumerable(Of KeyValuePair(Of TKey, TValue)).GetEnumerator
Return _internalDictionary.GetEnumerator
End Function
Public Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator
Return _internalDictionary.GetEnumerator
End Function
End Class
I can then access the elements via Key or Index:
Code:
Dim openWithCustom As New CustomKeyIndex(Of String, String)
openWithCustom.Add("txt", "notepad.exe")
openWithCustom.Add("bmp", "paint.exe")
openWithCustom.Add("dib", "paint.exe")
openWithCustom.Add("rtf", "wordpad.exe")
MessageBox.Show(openWithCustom.Item(3))
MessageBox.Show(openWithCustom.Item("txt"))
-tg
addendum: I'll admit though, it seems a bit hackish... there's probably a better way to go about it.
-
Jul 6th, 2015, 11:53 AM
#10
Re: Collection-like solution with both strong typing and keys
I had created my own class which implements an IDictionary and IList, which contains both a list and a Dictionary object. Simply, when you add and remove objects, you add and remove from both the dictionary and the list. When you reference by index then look at the List, by key, look at the Dictionary.
"Ok, my response to that is pending a Google search" - Bucky Katt.
"There are two types of people in the world: Those who can extrapolate from incomplete data sets." - Unk.
"Before you can 'think outside the box' you need to understand where the box is."
-
Jul 6th, 2015, 12:05 PM
#11
Re: Collection-like solution with both strong typing and keys
That seems a bit more brute-forcish especally when having to maintain both a list and dictionary. That's just my opinion though. I've seen others do that too. It just seems easier to overload the dictionary's .Item method to also accept an index... I guess in the end, it doesn't matter as the result is the same.
-tg
-
Jul 6th, 2015, 12:09 PM
#12
Re: Collection-like solution with both strong typing and keys
Actually... I'm curious as to how you handle some of the List methods, particularly the .Add ... how does the value get added to the Dictionary?
-tg
-
Jul 6th, 2015, 01:54 PM
#13
Re: Collection-like solution with both strong typing and keys
When you add an item, you need a key. Just like any other dictionary object. The list actually is a list of Key Value Pairs (I created my own object), so you can cross-reference from List to Dictionary and visa versa. Removing objects is a little tricky, but not overly so.
Regarding brute force: the dictionary index isn't necessarily the index an item was added. I'm not sure how you would override the Item method. Likewise, how do you 'add' at a specific index, since it doesn't appear a dictionary has those mechanisms.
"Ok, my response to that is pending a Google search" - Bucky Katt.
"There are two types of people in the world: Those who can extrapolate from incomplete data sets." - Unk.
"Before you can 'think outside the box' you need to understand where the box is."
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|