Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Esse aviso ocorre quando você usa AddressOf um método em um contexto de manipulador de eventos em que a assinatura do método não corresponde exatamente à assinatura delegada do evento. O Visual Basic permite conversão de delegados descontraída nesses cenários, mas o AddressOf operador se torna redundante porque o compilador deve criar um delegado wrapper de qualquer maneira.
Entender a conversão de delegado descontraída
O Visual Basic permite atribuir métodos a delegados mesmo quando suas assinaturas não correspondem exatamente, desde que a conversão seja segura. Isso é chamado de conversão de delegado descontraída e inclui:
- Tipos de parâmetro ampliados: um parâmetro de método pode ser um tipo mais amplo do que o parâmetro delegado.
- Tipos de retorno ampliados: um tipo de retorno de método pode ser mais estreito que o tipo de retorno delegado.
- Parâmetros omitidos: um método pode ter menos parâmetros do que o delegado.
-
Valores retornados descartados: uma função pode ser atribuída a um
Subdelegado.
Quando esse aviso ocorre
Esse aviso é exibido quando o Visual Basic pode lidar com a atribuição por meio de conversão descontraída, tornando o explícito AddressOf desnecessário.
Exemplo completo mostrando o aviso
O exemplo a seguir mostra um cenário que produz 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
Quando você compila esse código, o Visual Basic mostra o aviso BC42328 para as instruções que utilizam conversão de delegados flexível.
Por que AddressOf parece não ter "nenhum efeito"
A mensagem de aviso afirma que AddressOf "não tem efeito" porque o Visual Basic deve criar um delegado wrapper para a conversão descontraída, independentemente disso. O AddressOf operador não altera a forma como o compilador lida com a conversão: o mesmo resultado ocorre se você usa AddressOf ou não em cenários de conversão descontraídas.
No entanto, AddressOf ainda é sintaticamente necessário em instruções e AddHandler instruçõesRemoveHandler.
ID do erro: BC42328
Para corrigir este erro
Você tem várias opções dependendo de suas necessidades. Usando o DocumentProcessor exemplo anteriormente, aqui estão as diferentes maneiras de resolver o aviso de BC42328:
Opção 1: Atribuir a uma variável primeiro (preserva a semântica exata)
Public Sub DemonstrateHandler()
' Create delegate variable first - this eliminates the warning
Dim handler As EventHandler = AddressOf OnDocumentProcessed_Simple
AddHandler DocumentProcessed, handler
End Sub
Opção 2: corresponder exatamente à assinatura do 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
Opção 3: Usar uma expressão 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
Opção 4: Usar a Handles cláusula (se apropriado)
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
Opção 5: Atribuição direta para delegar variável
Public Sub DemonstrateHandler()
' Assign to delegate variable then use with AddHandler
Dim handler As EventHandler = AddressOf OnDocumentProcessed_Simple
AddHandler DocumentProcessed, handler
End Sub
Quando você pode ignorar este aviso
Esse aviso geralmente é seguro de ignorar quando:
- O método do manipulador omite intencionalmente os parâmetros de que não precisa.
- Você está usando uma assinatura de método mais simples para código mais limpo.
- O impacto no desempenho é insignificante para seu aplicativo.
- Você está fazendo protótipos ou escrevendo código utilitário rápido em que a clareza é mais importante do que a eficiência.
A conversão descontraída funciona corretamente; este aviso indica apenas uma pequena consideração de eficiência. O compilador cria automaticamente um delegado wrapper, que adiciona uma pequena sobrecarga de desempenho, mas não afeta a funcionalidade.
Exemplo de quando ignorar é apropriado
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