Option Strict 在 LINQ 语句中导致编译错误(隐式转换 'Object' 到 'Control')

Option Strict causing compiling error within LINQ statement (implicit conversion 'Object' to 'Control')

我们目前正在将一个 VB 项目转换为 C#,并首先启用 Option Strict。启用后,以下行会生成错误:

Dim visiblePanelCount As Integer = (From c As Control In pnl_AdminPageLinks.Controls 
                                     Where TypeOf (c) Is Panel AndAlso c.Visible 
                                     Select c).Count()

红色下划线在 As Control 上,错误为:

BC30512 Option Strict On disallows implicit conversions from 'Object' to 'Control'

我理解错误的含义,但无法理解 Object 类型的创建位置(因为我认为 .Controls 是类型 Control 的集合)。

第二个对我来说意义更小的例子是 "Object to DataRow" 这一行 As DataRow 下的相同错误:

Return (From dr As DataRow In MyDataTable.Rows ' error on As DataRow
        Select New MyClass() With {
            .Id = Convert.ToInt32(dr.Item("Id")),
            .UserId = Convert.ToInt32(dr.Item("UserId"))
        }).ToList()

我将代码转换为生成相同逻辑的 C#,所以不理解 VB.Net 的潜在问题。

请记住,LINQ 基于通用 IEnumerable(Of T) 接口,而 Controls 集合尽管仅包含控件,但并未实现 IEnumerable(Of Control)。它仅实现 IEnumerable,因此在枚举时,它仅提供 Object 引用。从 IEnumerableIEnumerable(Of T) 的方法是使用 Cast(Of T) 方法:

Dim visiblePanelCount = (From c In pnl_AdminPageLinks.Controls.Cast(Of Control)()
                         Where TypeOf (c) Is Panel AndAlso c.Visible 
                         Select c).Count()

您也可以通过调用 OfType(Of T) 来取消类型检查,这也与 Cast(Of T) 调用有关:

Dim visiblePanelCount = (From c In pnl_AdminPageLinks.Controls.OfType(Of Panel)()
                         Where c.Visible 
                         Select c).Count()

如果您只是选择原始查询项,也可以省略 VB 中的 Select 子句:

Dim visiblePanelCount = (From c In pnl_AdminPageLinks.Controls.OfType(Of Panel)()
                         Where c.Visible).Count()

鉴于 Count 方法也将进行过滤,您可以进一步简化该查询:

Dim visiblePanelCount = pnl_AdminPageLinks.Controls.OfType(Of Panel)().Count(Function(p) p.Visible)