【问题标题】:Converted my code from C# to VB.NET and now it's throwing an error将我的代码从 C# 转换为 VB.NET,现在它抛出了一个错误
【发布时间】:2012-03-22 08:55:51
【问题描述】:

谁能解释一下这个错误是什么意思?我是 VB 编程的新手,不明白这一点。

错误:未定义类型“var”

这是我的代码

Dim result = From s In reader.GetSales() _
                 Join c In reader.GetSalesRep() _
                     On s.SalesRepID Equals c.SalesRepID _
             Order By c.SalesRepID _
             Select New _
                 With { _
                     .SalesRepID = c.SalesRepID, _
                     .FirstName = c.FirstName
                     ''# truncated for brevity
                 }

Dim sb As New StringBuilder(50)
Dim path As String = "..\debug\CarSalesFiles\Commissions" _
                   + DateTime.Today.Year _
                   + DateTime.Today.Month _
                   + DateTime.Today.Day _
                   + ".txt"

If Not File.Exists(path) Then
    Using sw As StreamWriter = File.CreateText(path)

        ''# Here's the error line
        For Each var In result
            sb.Append(item.SalesRepID + _seperator)
            sb.Append(item.LastName + _seperator)
            sb.Append(item.FirstName + _seperator)
        Next

【问题讨论】:

    标签: vb.net


    【解决方案1】:

    这就是我想出的。您的匿名类型未设置ToList(),因此您的循环不会按预期工作。您还使用了var 变量,然后在循环中使用了item

    查看我的调整。

    ' I did NOT test your LINQ query, I just added .ToList()
    Dim results = (From s In reader.GetSales() _
                      Join c In reader.GetSalesRep() _
                      On s.SalesRepID Equals c.SalesRepID _
                      Order By c.SalesRepID _
                      Select New List(Of Results) With { _
                          .SalesRepID = c.SalesRepID, _
                          .FirstName = c.FirstName
                          ''# truncated for brevity
                      }).ToList() 
    
    '...
    
    If Not File.Exists(path) Then
        ''# not sure the purpose of the streamWriter here.
        ''# Using sw As StreamWriter = File.CreateText(path)
    
            For Each result In results ''# Notice the 'item' not 'var'
                sb.Append(result.SalesRepID + _seperator)
                ''# ...
            Next
    End If
    

    编辑

    在与@cHao 讨论时,如果您的代码中打开了Option Strict,您可能需要为您的匿名类型result 创建一个POCO ...见下文。

    Public Class Result
        Private Property _SalesRepID As Integer
        Public Property SalesRepID As Integer
            Get
                return _SalesRepID
            End Get
            Set(ByVal Value As Integer)
                _SalesRepID = value
            End Set
        End Property
    
        ' Wash / Rinse / Repeat for ALL your properties
    End Class
    

    然后在您的示例代码中

    ' Again, I did NOT test your LINQ query, I just added .ToList()
    Dim results As List(Of Result) = (From s In reader.GetSales() _
                                      Join c In reader.GetSalesRep() _
                                      On s.SalesRepID Equals c.SalesRepID _
                                      Order By c.SalesRepID _
                                      Select New Result With { _
                                         .SalesRepID = c.SalesRepID, _
                                         .FirstName = c.FirstName
                                         ''# truncated for brevity
                                      }).ToList()
    
    ' ....
    
    For Each result As Result In results ''# Notice the 'result' not 'var'
        sb.Append(result.SalesRepID + _seperator)
        ''# ...
    Next
    
    ' Apologies for minor mistakes, the SO editor isn't quite as awesome as Visual Studio.
    

    【讨论】:

    • 虽然是真的,虽然它确实解决了接下来会出现的问题......如果这是 the 问题,那么错误不会说明未声明的标识符' item' 而不是未定义的类型?
    • 所以使用上面的代码你会得到Error : Type 'item' is not defined?
    • 我会这么认为。我在这台机器上没有 VS,也不想安装它,但在我看来,问题在于 Option Infer 关闭而 Option Strict 开启,导致 For Each var/item/whatever In result 语法错误。
    • 请在 IDE 中测试。如果您使用的是最新版本的 VB.NET(我认为是 v10),上面的代码应该可以正常工作。您甚至不必添加Option Infer。我一直在我的项目中这样做没有问题。
    • 它与 VB 中的自动属性在同一条船上。它们现在也可以工作。 Public Property myProperty As Stringpublic string myProperty {get; set;} 相同
    【解决方案2】:

    C# 关键字 var 在 VB.NET 中没有直接等效项,而是需要设置 Option Infer On

    或者,您可以明确指定类型:

    For Each foo As Sale In result
    

    【讨论】:

    • 不幸的是,result 是作为匿名类型出现的,因此指定没有poco 的类型可能很困难。
    • @JustinMKeys 如果他没有将他的匿名类型设为List,那么For Each 循环将不会知道 var 是变量而不是类型。问题不在于循环。
    【解决方案3】:

    您似乎在使用“var”,但您尚未定义它。注意:在 VB 中,变量是用谓词 DIM 定义的。您需要在使用它之前声明一个变量。 VAR 的 C# 构造在此处不完全适用。但是,我自己并不是 VB 的忠实用户,但请记住,您可以这样做:

    DIM var(创建 var) DIM var as String(类型稍后声明)

    Dim 可以理解为“我正在声明一个变量,但还不能告诉你它的行为方式。”

    简单地说,在 VB 中,您可以在为其分配类型或值之前创建变量。但是,我会为您指出关于 DIM 和 VAR 差异的更好解释。

    Scott Hanselman - Back to Basics: var != Dim

    我假设您正在编写某种办公代码? C# 通常应该与使用 VB 一样好(如果在某些方面不是更好的话)。在处理 OFFICE 集成应用程序时,文章中提到了一个例外。

    希望这会有所帮助。

    【讨论】:

    • 各位读者,我自己一般更喜欢C#。这绝不表明一种代码比另一种更好(因为两者最终都被翻译成 CIL)。请不要根据“个人代码偏好”降级我的回复,因为大多数时候这是一个无声的话题。
    • 在 VB 中,在 For Each 循环中使用变量之前,您不必Dim 变量。 For Each item As result In results 工作得很好。或者,您也可以使用For Each item In results
    • @Zack: “moot”主题,而不是“静音”。
    【解决方案4】:

    试试这个:

    For Each item In result
    

    为此,您必须将 Option Infer 设置为 On。此外,您似乎正在使用 stringbuilder 作为最终写入文件的缓冲区。最好直接写入文件流。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-17
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多