.NET默认属性错误

时间:2009-04-25 03:06:57

标签: vb.net properties default

我有一个VB.NET项目,我可以使用索引迭代键和值字典对象的集合:


MyDictionary.Keys(idx)
MyDictionary.Values(idx)

当从测试项目中获取此代码并将其放入实际项目时,我收到以下错误:

  
    

'System.Collections.Generic.Dictionary(Of Double,String).KeyCollection'无法编入索引,因为它没有默认属性。

  

  
    

'System.Collections.Generic.Dictionary(Of Double,String).ValueCollection'无法编入索引,因为它没有默认属性。

  

这是使用VB.NET和VS 2008.我不知道从一个项目到下一个会导致此错误的项目有什么区别。该测试是一个控制台应用程序,该程序是一个winforms应用程序。

哪些条件会导致这些集合的默认属性发生变化?

编辑 - 感谢您提供的所有答案,告诉我如何遍历字典。然而,这些答案回答了我为什么可以在一个项目中使用索引而不是另一个项目的问题。我是否应该无法将代码从一个.net项目复制并粘贴到另一个.net项目并使其工作相同?并且,不,选项严格,不是问题的原因。

修改 - 尝试重现我所看到的内容:

  • 使用VS 2008创建新的VB.NET控制台应用程序
  • 将以下代码复制并粘贴到模块中:

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

在子搜索中“dtf.Keys(idx)= 0”的行中,将光标放在右括号和退格后,您应该得到一个工具提示,上面写着“< Extension> ElementAtOrDefault(index as Integer)as Double - index:要检索的索引的基于零的元素。

我没有在我的其他项目中得到它。即使看起来我有相同的参考和设置。

3 个答案:

答案 0 :(得分:4)

KeyCollection没有实现这样的索引器,你必须通过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

使用for(; i ++;)循环不是正确的方法来通过你的哈希表(字典),因为它不是一个数组,它真的没有数组索引的概念(数组[索引])

答案 1 :(得分:3)

我打赌你的真实项目有OPTION STRICT ON,因为所有项目都应该,并且你的测试项目已经关闭了。这就是为什么你的测试项目没有出现编译错误的原因。

编辑:海报上说两个项目都有OPTION STRICT ON。这使得这更有趣。

我仍然认为造成这种差异的最可能原因是,在一种情况下,编译器编译了代码并看到了错误;但在另一种情况下,编译器没有编译代码。这是同一台机器上同一版本的Visual Studio吗?两种情况下的.NET Framework版本相同吗?

这些都是同一类型的项目,例如,它们都是控制台应用程序吗?我问,因为ASP.NET网站“项目”通常不会尝试编译代码,直到调用代码。如果您的测试项目是一个“项目”,并且如果您没有实际测试代码(也就是说,如果您实际上没有进入此代码并且看到它有效),那么您可能已经假设了这样的事实:可以按F5意味着所有代码都已编译,而不是。

我的下一个想法是看两种情况下MyDictionary是否真的是同一类型。

除此之外,如果你真的需要知道为什么会发生这种情况,我会复制“真正的”项目,并开始将其更改为越来越像测试项目。这可能是最初的大规模删除问题。我会一直改变它,直到找到问题,或直到两者相同。

编辑2:默认控制台项目导入System.Linq命名空间(请参阅项目属性中的“参考”选项卡)。此导入将ElementAtOrDefault扩展方法纳入范围。这个扩展方法扩展了IEnumerable(Of T);在你的情况下IEnumerable(Of Double),这是Keys属性实现的。

令我惊讶的是,VB.NET正在自动应用此扩展方法。在C#中,需要明确命名该方法。

如果删除System.Linq的导入,您会发现测试应用程序与生产应用程序的错误相同。

答案 2 :(得分:2)

Dictionary(Of TKey,TValue)的Keys和Values属性没有索引器属性。它们是ICollection与IList的实现,因此不支持Index的访问。如果你想迭代一个字典,最好的方法是For Each循环。

For Each pair in MyDictionary
  Dim key = pair.Key
  Dim value = pair.Value
Next

编辑

您是否检查过以确保在两个项目中都引用了System.Core,并且您有System.Linq的项目级别导入?这是我能想到的唯一能在ElementAtOrDefault中产生差异的东西,这是system.Core中的一个方法。

我仍然有点困惑为什么这个方法将被绑定到一个简单的索引器。去研究那个