Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
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