Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Esta advertencia se produce cuando se usa AddressOf con un método en un contexto de controlador de eventos en el que la firma del método no coincide exactamente con la firma del delegado del evento. Visual Basic permite la conversión de delegados relajada en estos escenarios, pero el AddressOf operador se vuelve redundante porque el compilador debe crear un delegado contenedor de todos modos.
Descripción de la conversión de delegados relajada
Visual Basic permite asignar métodos a delegados incluso cuando sus firmas no coinciden exactamente, siempre y cuando la conversión sea segura. Esto se denomina conversión de delegado flexible e incluye:
- Tipos de parámetros ampliados: un parámetro de método puede ser un tipo más amplio que el parámetro delegado.
- Tipos devueltos anchos: un tipo de valor devuelto de método puede ser más estrecho que el tipo de valor devuelto delegado.
- Parámetros omitidos: un método puede tener menos parámetros que el delegado.
-
Valores devueltos quitados: se puede asignar una función a un
Subdelegado.
Cuando se produce esta advertencia
Esta advertencia aparece cuando Visual Basic puede controlar la asignación a través de la conversión relajada, lo que hace que el elemento explícito AddressOf sea innecesario.
Ejemplo completo que muestra la advertencia
En el ejemplo siguiente se muestra un escenario que genera BC42328:
Public Class DocumentProcessor
' Standard .NET event using EventHandler
Public Event DocumentProcessed As EventHandler
' Custom event with different signature
Public Event StatusChanged As Action(Of String)
' Handlers with different signatures
' Exact match for EventHandler - no warning
Private Sub OnDocumentProcessed_Exact(sender As Object, e As EventArgs)
Console.WriteLine("Document processed (exact signature)")
End Sub
' Simplified handler - causes BC42328 with EventHandler
Private Sub OnDocumentProcessed_Simple()
Console.WriteLine("Document processed (simple)")
End Sub
' Handler for custom event - exact match
Private Sub OnStatusChanged_Exact(message As String)
Console.WriteLine($"Status: {message}")
End Sub
' Handler with ignored parameters - causes BC42328 with custom event
Private Sub OnStatusChanged_Simple()
Console.WriteLine("Status changed")
End Sub
Public Sub DemonstrateWarnings()
Console.WriteLine("Setting up event handlers...")
' These work without warnings (exact matches)
AddHandler DocumentProcessed, AddressOf OnDocumentProcessed_Exact
AddHandler StatusChanged, AddressOf OnStatusChanged_Exact
' These generate BC42328 warnings (relaxed conversions)
AddHandler DocumentProcessed, AddressOf OnDocumentProcessed_Simple
AddHandler StatusChanged, AddressOf OnStatusChanged_Simple
' Fire the events
RaiseEvent DocumentProcessed(Me, EventArgs.Empty)
RaiseEvent StatusChanged("Processing complete")
End Sub
Public Sub DemonstrateSolutions()
Console.WriteLine("Using solutions to avoid warnings...")
' Solution 1: Assign to variable first
Dim handler1 As EventHandler = AddressOf OnDocumentProcessed_Simple
AddHandler DocumentProcessed, handler1
' Solution 2: Use lambda expression
AddHandler DocumentProcessed, Sub(s, e) OnDocumentProcessed_Simple()
' Solution 3: Direct assignment to delegate variable
Dim handler2 As Action(Of String) = AddressOf OnStatusChanged_Simple
AddHandler StatusChanged, handler2
' Fire the events
RaiseEvent DocumentProcessed(Me, EventArgs.Empty)
RaiseEvent StatusChanged("All solutions work")
End Sub
End Class
Al compilar este código, Visual Basic muestra la advertencia BC42328 para las sentencias que usan la AddHandler conversión relajada de delegados.
¿Por qué AddressOf parece tener "ningún efecto"
El mensaje de advertencia indica que AddressOf "no tiene ningún efecto" porque Visual Basic debe crear un delegado contenedor para la conversión relajada independientemente. El AddressOf operador no cambia el modo en que el compilador controla la conversión: el mismo resultado se produce si se usa AddressOf o no en escenarios de conversión relajados.
Sin embargo, AddressOf todavía se requiere sintácticamente en AddHandler las instrucciones y RemoveHandler .
Identificador de error: BC42328
Para corregir este error
Tiene varias opciones en función de sus necesidades. Con el DocumentProcessor ejemplo anterior, estas son las distintas maneras de resolver la advertencia de BC42328:
Opción 1: Asignar primero a una variable (conserva la semántica exacta)
Public Sub DemonstrateHandler()
' Create delegate variable first - this eliminates the warning
Dim handler As EventHandler = AddressOf OnDocumentProcessed_Simple
AddHandler DocumentProcessed, handler
End Sub
Opción 2: Coincidencia exacta con la firma del delegado
' Change the method signature to match EventHandler exactly
Private Sub OnDocumentProcessed_Simple(sender As Object, e As EventArgs)
' You can ignore the parameters if you don't need them
Console.WriteLine("Document processed (simple)")
End Sub
Public Sub DemonstrateHandler()
' Now this works without warning
AddHandler DocumentProcessed, AddressOf OnDocumentProcessed_Simple
End Sub
Opción 3: Usar una expresión lambda
Public Sub DemonstrateHandler()
' Wrap the method call in a lambda that matches the signature
AddHandler DocumentProcessed, Sub(sender, e) OnDocumentProcessed_Simple()
' Or create a more complex lambda inline
AddHandler DocumentProcessed,
Sub(sender, e)
Console.WriteLine($"Event from {sender}")
OnDocumentProcessed_Simple()
End Sub
End Sub
Opción 4: Usar la Handles cláusula (si procede)
Public Class DocumentHandler
' Declare the event source with WithEvents
Private WithEvents processor As DocumentProcessor
' Use Handles clause - no AddHandler needed
Private Sub OnDocumentComplete() Handles processor.DocumentProcessed
Console.WriteLine("Document processing is done!")
End Sub
End Class
Opción 5: Asignación directa a la variable de delegado
Public Sub DemonstrateHandler()
' Assign to delegate variable then use with AddHandler
Dim handler As EventHandler = AddressOf OnDocumentProcessed_Simple
AddHandler DocumentProcessed, handler
End Sub
Cuando se puede omitir esta advertencia
Esta advertencia suele ser segura para omitir cuando:
- El método de controlador omite intencionadamente los parámetros que no necesita.
- Está usando una firma de método más sencilla para código más limpio.
- El impacto en el rendimiento es insignificante para la aplicación.
- Va a crear prototipos o escribir código de utilidad rápido donde la claridad es más importante que la eficacia.
La conversión relajada funciona correctamente; esta advertencia solo indica una consideración de eficacia menor. El compilador crea automáticamente un delegado contenedor, que agrega una pequeña sobrecarga de rendimiento, pero no afecta a la funcionalidad.
Ejemplo de cuándo omitir es adecuado
Public Class QuickLogger
Public Event LogMessage As Action(Of String, DateTime)
' Simple handler that ignores the timestamp parameter
Private Sub WriteToConsole()
Console.WriteLine("Something was logged")
End Sub
Public Sub SetupLogging()
' This generates BC42328, but it's fine for simple scenarios
AddHandler LogMessage, AddressOf WriteToConsole
End Sub
End Class