Option Strict causing compiling error within LINQ statement (implicit conversion 'Object' to 'Control')
Estamos convirtiendo actualmente un proyecto VB a C#, y comenzando por habilitar Option Strict. Cuando está activada, la siguiente línea genera un error:
Dim visiblePanelCount As Integer = (From c As Control In pnl_AdminPageLinks.Controls
Where TypeOf (c) Is Panel AndAlso c.Visible
Select c).Count()
La línea roja está en As Control
con el error:
BC30512 Option Strict Sobre las conversiones implícitas de 'Objeto' a 'Control '
Entiendo lo que significa el error, pero no puedo entender dónde es el tipo de Object
está siendo creado (como creo que .Controls
es una colección de tipo Control
).
Un segundo ejemplo que tiene menos sentido para mí es "Objeto a DataRow" mismo error bajo As DataRow
en esta línea:
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()
Convierto el código a C# que generó la misma lógica, así que no entienda VB. El problema subyacente de Net.
Pregunta hecha hace 3 años, 4 meses, 28 días - Por codealchemyf00f
3 Respuestas:
-
Recuerde que LINQ está basado en el genérico
IEnumerable(Of T)
interfaz y esoControls
la colección, a pesar de contener sólo controles, no implementaIEnumerable(Of Control)
. Sólo implementaIEnumerable
así, cuando se enumera, proporciona unObject
sólo referencia. La manera de salir deIEnumerable
aIEnumerable(Of T)
está con elCast(Of T)
método:Dim visiblePanelCount = (From c In pnl_AdminPageLinks.Controls.Cast(Of Control)() Where TypeOf (c) Is Panel AndAlso c.Visible Select c).Count()
Puedes eliminar el tipo de cheque llamando
OfType(Of T)
también, que también burla losCast(Of T)
llamada:Dim visiblePanelCount = (From c In pnl_AdminPageLinks.Controls.OfType(Of Panel)() Where c.Visible Select c).Count()
También puede omitir
Select
cláusula en VB si usted está simplemente seleccionando el elemento de consulta original:Dim visiblePanelCount = (From c In pnl_AdminPageLinks.Controls.OfType(Of Panel)() Where c.Visible).Count()
Dado que
Count
método también filtrará, usted puede simplificar esa consulta aún más:Dim visiblePanelCount = pnl_AdminPageLinks.Controls.OfType(Of Panel)().Count(Function(p) p.Visible)
Respondida el Dec 17, 2020 a las 11:55 - por scriptwarrior
Votos positivos: 0 | Votos negativos: 0 -
El error que estás experimentando se debe a cómo Option Strict en VB.NET trata las conversiones implícitas de tipos. Cuando Option Strict está habilitado, todas las conversiones implícitas deben ser explícitas para evitar pérdidas de datos inadvertidas.
En tu primer ejemplo, el problema está en la parte de la declaración de la variable en la expresión LINQ. Cuando usas
From c As Control In pnl_AdminPageLinks.Controls
, el tipo de datos dec
se infiere comoObject
en lugar deControl
debido a cómo LINQ trata las colecciones genéricas. Por lo tanto, al intentar usarAs Control
en esa declaración, estás intentando convertir unObject
a unControl
, lo cual es una conversión implícita que no es válida cuando Option Strict está habilitado.Una forma de resolver esto es cambiar la identificación del tipo de
c
dentro de la expresión LINQ para evitar la conversión implícita. Puedes lograrlo cast o convertir el objetoc
en unControl
de manera explícita, de la siguiente manera:csharp Dim visiblePanelCount As Integer = (From c In pnl_AdminPageLinks.Controls.Cast(Of Control)() Where TypeOf (c) Is Panel AndAlso c.Visible Select c).Count()
En cuanto al segundo ejemplo, el problema es similar. Debes cambiar la identificación del tipo de
dr
aDataRow
dentro de la expresión LINQ para evitar la conversión implícita. Puedes hacerlo de la siguiente manera:csharp Return (From dr In MyDataTable.Rows.Cast(Of DataRow)() Select New MyClass() With { .Id = Convert.ToInt32(dr.Item("Id")), .UserId = Convert.ToInt32(dr.Item("UserId")) }).ToList()
Al hacer estos cambios, deberías poder compilar tu código sin errores con Option Strict habilitado en VB.NET.
Respondida el Dec 18, 2020 a las 11:55 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Problema 1: Conversión de
Object
aControl
En la siguiente línea:
vb Dim visiblePanelCount As Integer = (From c As Control In
El tipo de
c
se infiere comoObject
. Esto se debe a que la cláusulaFrom
en una consulta LINQ devuelve un conjunto de objetos anónimos. Para resolver este problema, puedes especificar explícitamente el tipo dec
comoControl
:vb Dim visiblePanelCount As Integer = (From c As Control In
Problema 2: Conversión de
Object
aDataRow
En la siguiente línea:
vb Return (From dr As DataRow In
El tipo de
dr
también se infiere comoObject
. Esto se debe a que la propiedadRows
de unaDataTable
devuelve una colección deDataRow
anónimos. Para resolver este problema, puedes especificar explícitamente el tipo dedr
comoDataRow
:vb Return (From dr As DataRow In
Solución de C Las conversiones de tipo explícitas en C
se pueden lograr utilizando el operador
Problema 1:as
. Aquí tienes las líneas conver neumáticos:csharp int visiblePanelCount = (from Control c in panel.Controls
Problema 2:
csharp return (from DataRow
Respondida el Dec 18, 2020 a las 11:59 - por Gemini
Votos positivos: 0 | Votos negativos: 0