【问题标题】:.NET Default Properties Error [duplicate].NET 默认属性错误 [重复]
【发布时间】:2009-04-25 03:06:56
【问题描述】:

我有一个 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 项目复制并粘贴到另一个项目并使其工作相同?而且,不,选项 strict 不是问题的原因。

编辑 - 尝试重现我所看到的:

  • 使用 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”的行中,将光标放在右括号和退格之后,您应该会得到一个工具提示,上面写着“ ElementAtOrDefault(index as Integer) as Double - index:要检索的索引的从零开始的元素。

我没有在我的其他项目中得到这个。尽管看起来我有相同的引用和设置。

【问题讨论】:

  • 根据错误,您使用的是双键?这是故意的吗?
  • @neodymium:感谢您发布详细信息。我会调查的。您还应该提供有关“真实”项目的一些详细信息。
  • @neodymium:既然您知道问题所在,我建议您编辑主题行以反映实际情况。该问题实际上与默认属性无关。根据您当前的主题行,遇到相同问题的其他人可能不会找到此问题。
  • @John Saunders:上面列出的原始错误实际上与默认属性有关。如果这些是您收到的错误,那么这可能就是您要搜索的内容。如果您觉得有更好的标题,请随时自行更改。
  • 我的问题很相似 - 一个控制台应用程序和一个测试项目无法匹配它在 XElement 树的行走。两者都引用了 System.Xml.Linq,但是当我将 System.Linq 添加到测试项目时,它开始与控制台应用程序一样工作 - 即使控制台应用程序没有引用该库! WTF?!

标签: vb.net properties default


【解决方案1】:

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++;) 循环不是通过哈希表(字典)的正确方法,因为它不是数组,它实际上没有数组索引的概念(数组 [索引])

【讨论】:

  • 您的 vb.net 示例已损坏。我修好了。
  • @Joel,谢谢...我好几年没做过 VB 了 :)
  • 这并不能回答我为什么可以在一个项目中使用索引而不能在另一个项目中使用索引的问题。
  • 我不知道,我永远不想按键索引使用哈希表,因为这是不可预测的。索引与哈希表无关,甚至不确定为什么 MS 会在 LINQ 中实现它。使用 Key 而不是索引,您将变得更加安全/无错误。
  • 我认为没有理由在这段代码中使用 LINQ
【解决方案2】:

我敢打赌你的真实项目有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 的 Import,您会发现您的测试应用程序与生产应用程序出现相同的错误。

【讨论】:

  • 我在两个项目中都有严格的选项。
  • 是的,我错过了 System.Linq 导入。谢谢。
  • 您应该将Edit2 移到顶部。这就是答案。知道这种奇怪而可怕的行为记录在哪里会很有趣。 ++
  • 编辑 VB.NET 语言规范 11.21.3:默认查询索引器。每个元素类型为 T 并且还没有默认属性的可查询集合类型都被认为具有以下一般形式的默认属性: Public ReadOnly Default Property Item(index As Integer) As T Get Return Me.ElementAtOrDefault(index) End 获取 End 属性
【解决方案3】:

Dictionary(Of TKey,TValue) 的 Keys 和 Values 属性没有索引器属性。它们是 ICollection 与 IList 的实现,因此不支持通过索引进行访问。如果要遍历字典,最好的方法是 For Each 循环。

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

编辑

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

我仍然有点困惑,为什么该方法会被绑定到一个简单的索引器。打算调查一下

【讨论】:

  • 这并不能回答我为什么可以在一个项目中使用索引而不能在另一个项目中使用索引的问题。
  • 是的,我错过了 System.Linq 导入。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-27
  • 1970-01-01
  • 2015-09-07
  • 2016-05-06
  • 2011-01-28
相关资源
最近更新 更多