I have a VB.NET project where I am able to iterate through the keys and values collections of a dictionary object using an index:
MyDictionary.Keys(idx)
MyDictionary.Values(idx)
When this code is taken from the test project and placed into the real project I get the following error:
'System.Collections.Generic.Dictionary(Of Double, String).KeyCollection' cannot be indexed because it has no default property.
and
'System.Collections.Generic.Dictionary(Of Double, String).ValueCollection' cannot be indexed because it has no default property.
This is using VB.NET and VS 2008. I don't know what the difference would be from one project to the next that would cause this error. The test is a console application and the program is a winforms app.
What conditions would cause the default property of these collections to change?
Edit - Thank you for all of the answers that tell me how to loop through a dictionary. Those, answers, however, do not answer my question of why I can use an index in one project and not the other. Should I not be able to copy and paste the code from one .net project to another and have it work the same? And, no, option strict, is not the cause of the problem.
Edit - Attempt to reproduce what I'm seeing:
Imports System.Collections
Imports System.Collections.Generic
Module Module1
Public dtf As Dictionary(Of Double, String)
Public Sub BuildDictionary()
dtf = New Dictionary(Of Double, String)
dtf.Add(1.0, "1")
dtf.Add(0.0, "0")
End Sub
Public Sub Search()
For idx As Integer = 0 To dtf.Keys.Count - 1
If dtf.Keys(idx) = 0 Then
Exit Sub
End If
Next
End Sub
Sub Main()
End Sub
End Module
In the line in sub search that says "dtf.Keys(idx) = 0" place your cursor after the right parenthesis and backspace you should get a tooltip that says, "<Extension> ElementAtOrDefault(index as Integer) as Double - index: the zero based element of the index to retrieve.
I am not getting that in my other project. Even though it seem I have the same references and settings.
KeyCollection does not implement indexers like that, you must enumerate through the MyDictionary.Keys.
c#
foreach(double key in MyDictionary.Keys)
Console.Write( MyDictionary[ key ] )
vb
For Each key As Double in MyDictionary.Keys
Console.Write( MyDictionary( key )
Next key
Looping with a for(;i++;) wouldn't be the correct way of going through your hashtable (dictionary) since it is not an array it really has no concept of an array index (array[index])
I bet your real project had OPTION STRICT ON
, as all projects should, and that your test project had it OFF. That's why you didn't get a compiler error in your test project.
EDIT: the poster says he has OPTION STRICT ON for both projects. That makes this more interesting.
I still think the most likely reason for this difference is that in one case, the compiler compiled the code and saw the error; but in the other case, the compiler didn't comile the code. Is this the same version of Visual Studio on the same machine at the same time? Same .NET Framework version in both cases?
Are these both the same type of project, for instance, are they both console applications? I ask because ASP.NET Web Site "projects" usually don't attempt to compile code until the code is called. If your test project were such a "project", and if you didn't actualy test the code (that is, if you didn't actually step into this code and see it work), then you might have assumed that the fact you could press F5 meant that all the code was compiled, when it wasn't.
My next thoughts would be to see if MyDictionary was really of the same type in both cases.
Beyond that, if you really need to know why this happened, I'd make a copy of the "real" project, and start changing it to be more and more like the test project. This would probably be a matter of mass deletions at first. I'd keep changing it either until the problem was found, or until the two were identical.
EDIT 2: The default console project imports the System.Linq namespace (see the "References" tab in project properties). This import brings the ElementAtOrDefault extension method into scope. This extension method extends IEnumerable(Of T); in your case IEnumerable(Of Double), which is what the Keys property implements.
What surprises me about this is that VB.NET is automatically applying this extension method. In C#, the method would need to be explicitly named.
If you remove the Import of System.Linq, you'll find that your test application gets the same error as the production application.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With