Výraz AddressOf nemá v tomto kontextu žádný vliv, protože argument metody "AddressOf" vyžaduje uvolněný převod na typ delegáta události.

K tomuto upozornění dochází, když použijete AddressOf s metodou v kontextu obslužné rutiny události, kde podpis metody přesně neodpovídá podpisu delegáta události. Visual Basic umožňuje uvolněný převod delegáta v těchto scénářích, ale AddressOf operátor se stane redundantní, protože kompilátor musí přesto vytvořit delegáta obálky.

Vysvětlení uvolněných převodů delegátů

Visual Basic umožňuje přiřazovat metody delegátům, i když se jejich podpisy neshodují přesně, pokud je převod bezpečný. Označuje se jako uvolněný převod delegáta a zahrnuje:

  • Rozšířené typy parametrů: Parametr metody může být širším typem než parametr delegáta.
  • Rozšířené návratové typy: Návratový typ metody může být užší než návratový typ delegáta.
  • Vynechané parametry: Metoda může mít méně parametrů než delegát.
  • Vyřazené návratové hodnoty: Funkci lze přiřadit delegátovi Sub .

Pokud k tomuto upozornění dojde

Toto upozornění se zobrazí, když Visual Basic dokáže zpracovat přiřazení prostřednictvím uvolněného převodu, což explicitně AddressOf nepotřebné.

Kompletní příklad znázorňující upozornění

Následující příklad ukazuje jeden scénář, který vytváří 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

Při kompilaci tohoto kódu Visual Basic zobrazí upozornění BC42328 pro ty příkazy, které využívají uvolněnou konverzi delegáta.

Proč se zdá, že AddressOf nemá žádný vliv

Zpráva upozornění uvádí, že "nemá žádný účinek", AddressOf protože Visual Basic musí vytvořit delegát obálky pro uvolněný převod bez ohledu na to. Operátor AddressOf nezmění způsob zpracování převodu kompilátoru: stejný výsledek se projeví bez ohledu na to, jestli použijete AddressOf nebo ne v uvolněných scénářích převodu.

AddressOf Je však stále syntakticky vyžadován v AddHandler příkazech a RemoveHandler příkazech.

ID chyby: BC42328

Oprava této chyby

V závislosti na vašich potřebách máte několik možností. S využitím DocumentProcessor příkladu z předchozí části jsou zde různé způsoby řešení upozornění BC42328:

Možnost 1: Nejprve přiřaďte proměnné (zachovává přesnou sémantiku)

Public Sub DemonstrateHandler()
    ' Create delegate variable first - this eliminates the warning
    Dim handler As EventHandler = AddressOf OnDocumentProcessed_Simple
    AddHandler DocumentProcessed, handler
End Sub

Možnost 2: Přesně odpovídat podpisu delegáta

' 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

Možnost 3: Použití výrazu 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

Možnost 4: Použijte klauzuli Handles (pokud je to vhodné).

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

Možnost 5: Přímé přiřazení delegátní proměnné

Public Sub DemonstrateHandler()
    ' Assign to delegate variable then use with AddHandler
    Dim handler As EventHandler = AddressOf OnDocumentProcessed_Simple
    AddHandler DocumentProcessed, handler
End Sub

Kdy toto upozornění můžete ignorovat

Toto upozornění je často bezpečné ignorovat v těchto případech:

  • Metoda obslužné rutiny záměrně vynechá parametry, které nepotřebuje.
  • Pro čistější kód používáte jednodušší podpis metody.
  • Dopad na výkon je pro vaši aplikaci zanedbatelný.
  • Pracujete na vytváření prototypů nebo psaní rychlého užitkového kódu, kde je srozumitelnost důležitější než efektivita.

Uvolněný převod funguje správně; toto upozornění pouze značí menší aspekty efektivity. Kompilátor automaticky vytvoří obalový delegát, což přidá malou výkonnostní režii, ale neovlivňuje funkčnost.

Příklad, kdy je vhodné ignorovat

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

Viz také