Compartilhar via


A expressão 'AddressOf' não tem efeito nesse contexto porque o argumento do método para 'AddressOf' requer uma conversão descontraída para o tipo delegado do evento

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 Sub delegado.

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

Consulte também