You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET中BindingList类型转换与If表达式类型推断错误求助

解决VB.NET开发中的两个类型错误

错误1:类型转换失败

报错信息:无法将类型为System.Collections.Generic.List1[VB$AnonymousType_15`7[System.String,System.String,System.String,System.Object,System.Object,System.Object,System.String]]`的对象转换为`System.Collections.Generic.IList`1[ItemCards2]`
报错代码行:

bindingSource = New BindingSource With {.DataSource = New BindingList(Of ItemCards2)(CType(Cardex.ToList(), IList(Of ItemCards2)))}

问题原因

Linq查询的Select语句返回的是匿名类型集合,而非ItemCards2类型的实例集合。直接将匿名类型列表强制转换为IList(Of ItemCards2)会因类型不匹配导致转换失败。

修复方案

在Linq的Select子句中,直接创建ItemCards2的实例,替代生成匿名类型:

Select New ItemCards2 With {
    .ITEM = ITEM,
    .PRODUCTIONNAME = PRODUCTIONNAME,
    .BRAND = BRAND,
    .PIQ = If(PIQ <> 0, PIQ, 0),
    .SIQ = If(SIQ <> 0, SIQ, 0),
    .BLC = If(BLC <> 0, BLC, 0),
    .STATUS = STATUS
}

错误2:类型推断错误

报错信息:无法推断通用类型,因为存在多种可能类型
报错代码行:

PIQ = If(PIQ <> CInt("0"), PIQ, ""),
SIQ = If(SIQ <> CInt("0"), SIQ, ""),
BLC = If(BLC <> CInt("0"), BLC, ""),

问题原因

If语句的两个分支返回值类型不一致:第一个分支返回Integer类型(PIQ/SIQ/BLC的数值),第二个分支返回String类型(空字符串"")。VB.NET编译器无法确定最终返回类型,因此报错。同时,ItemCards2类中PIQ、SIQ、BLC的属性类型为Integer,本身也不能接受字符串值,即使编译通过也会引发运行时错误。

修复方案

保持类型一致,将空字符串替换为0(匹配属性的Integer类型)。如果需要在界面上显示空值,不要修改数据类型,可通过DataGridView的单元格格式设置实现:

PIQ = If(PIQ <> 0, PIQ, 0),
SIQ = If(SIQ <> 0, SIQ, 0),
BLC = If(BLC <> 0, BLC, 0),

完整修正代码

Public Class Form2
    Private bindingSource As BindingSource = Nothing
    Private MasterItem,
        PurchaseDetails,
        SalesDetails As New List(Of ItemCards2)
    Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        LoadLINQ()
    End Sub

    Private Function CreateConnection() As String
        Return ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\TRIAL2.accdb;Persist Security Info=False;")
    End Function
    Private Sub LoadLINQ()
        Const Qry_MST = "SELECT * FROM MASTERITEM"

        Const Qry_PI = "SELECT a.ITEM, '' AS PRODUCTIONNAME, '' AS BRAND, 0 AS LSQ, 0 AS TPIQ, a.QTY AS PIQ, 0 AS TSIQ, 0 AS SIQ, 0 AS TRSQ, 0 AS RSQ, 0 AS TRPQ, 0 AS RPQ,  0 AS BLC FROM (PurchaseDetails a INNER JOIN" &
                       " Purchase b ON a.INVONO = b.INVONO) INNER JOIN" &
                       " CUSTCODE c On b.CUSTCODE = c.CUSTCODE" &
                       " WHERE b.DATEINVO >= CDate('01/01/2024')" &
                       " AND c.GROUP IS NULL"
        Const Qry_SI = "SELECT a.ITEM, '' AS PRODUCTIONNAME, '' AS BRAND, 0 AS LSQ, 0 AS TPIQ,   0 AS PIQ, 0 AS TSIQ, a.QTY AS SIQ, 0 AS TRSQ, 0 AS RSQ, 0 AS TRPQ, 0 AS RPQ, 0 AS BLC FROM (SalesDetails a INNER JOIN" &
                       " Sales b ON a.INVONO = b.INVONO) INNER JOIN" &
                       " CUSTCODE c ON b.CUSTCODE = c.CUSTCODE" &
                       " WHERE b.DATEINVO >= CDATE('01/01/2024')" &
                       " AND c.GROUP IS NULL"
        Using Connection = New OleDbConnection(CreateConnection())
            With Connection
                MasterItem = CType(Connection.Query(Of ItemCards2)(Qry_MST), List(Of ItemCards2))
                PurchaseDetails = CType(Connection.Query(Of ItemCards2)(Qry_PI), List(Of ItemCards2))
                SalesDetails = CType(Connection.Query(Of ItemCards2)(Qry_SI), List(Of ItemCards2))
            End With
        End Using
        Dim Cardex =
           From card In PurchaseDetails.Union(SalesDetails)
           Join mst In MasterItem On card.ITEM Equals mst.ITEM
           Group card By card.ITEM, mst.PRODUCTIONNAME, mst.BRAND Into Group
           Let PIQ = (From x In Group Select x.PIQ).Sum
           Let SIQ = (From x In Group Select x.SIQ).Sum
           Let BLC = (PIQ) - (SIQ)
           Let STATUS = If(BLC < 24, "NEED TO PRODUCE", "")
           Select New ItemCards2 With {
               .ITEM = ITEM,
               .PRODUCTIONNAME = PRODUCTIONNAME,
               .BRAND = BRAND,
               .PIQ = If(PIQ <> 0, PIQ, 0),
               .SIQ = If(SIQ <> 0, SIQ, 0),
               .BLC = If(BLC <> 0, BLC, 0),
               .STATUS = STATUS
           }
           Order By ITEM
        bindingSource = New BindingSource With {.DataSource = New BindingList(Of ItemCards2)(Cardex.ToList())}
        DataGridView1.DataSource = bindingSource
    End Sub
End Class
Public Class ItemCards2
    Public Property ITEM() As String
    Public Property PRODUCTIONNAME As String
    Public Property BRAND As String
    Public Property PIQ As Integer
    Public Property SIQ As Integer
    Public Property BLC As Integer
    Public Property STATUS As String
End Class

内容的提问来源于stack exchange,提问作者user22579796

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 02:29:54