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
引用。从 IEnumerable
到 IEnumerable(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)
我们目前正在将一个 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
引用。从 IEnumerable
到 IEnumerable(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)