Skip to content

Commit 27c062e

Browse files
CopilotBillWagner
andcommitted
Add comprehensive examples to BC42328.md to improve clarity
Co-authored-by: BillWagner <[email protected]>
1 parent 36d4a12 commit 27c062e

File tree

3 files changed

+295
-41
lines changed

3 files changed

+295
-41
lines changed

docs/visual-basic/misc/bc42328.md

Lines changed: 204 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,46 @@ Visual Basic allows you to assign methods to delegates even when their signature
2424

2525
## When this warning occurs
2626

27-
This warning appears when Visual Basic can handle the assignment through relaxed conversion, making the explicit `AddressOf` unnecessary. For example:
27+
This warning appears when Visual Basic can handle the assignment through relaxed conversion, making the explicit `AddressOf` unnecessary.
2828

29-
```vb
30-
' Event delegate expects (sender As Object, e As EventArgs)
31-
Public Event SomeEvent As EventHandler
32-
33-
' Method with exact signature - no warning
34-
Sub Handler1(sender As Object, e As EventArgs)
35-
' Implementation
36-
End Sub
37-
38-
' Method with omitted parameters - causes BC42328
39-
Sub Handler2()
40-
' Implementation
41-
End Sub
29+
### Complete example showing the warning
4230

43-
' Using AddHandler with exact match - no warning
44-
AddHandler SomeEvent, AddressOf Handler1
31+
Here's a realistic scenario where you'll encounter BC42328:
4532

46-
' Using AddHandler with relaxed conversion - causes BC42328
47-
AddHandler SomeEvent, AddressOf Handler2
33+
```vb
34+
Public Class FileProcessor
35+
' Define an event using the standard EventHandler delegate
36+
' EventHandler expects: Sub(sender As Object, e As EventArgs)
37+
Public Event ProcessingComplete As EventHandler
38+
39+
' Method with exact signature - no warning
40+
Private Sub OnProcessingComplete(sender As Object, e As EventArgs)
41+
Console.WriteLine($"Processing completed by {sender}")
42+
End Sub
43+
44+
' Method with simplified signature - this causes BC42328 warning
45+
Private Sub OnSimpleComplete()
46+
Console.WriteLine("Processing is done!")
47+
End Sub
48+
49+
Public Sub StartProcessing()
50+
' This works fine - exact signature match
51+
AddHandler ProcessingComplete, AddressOf OnProcessingComplete
52+
53+
' This generates BC42328 warning:
54+
' "The 'AddressOf' expression has no effect in this context because
55+
' the method argument to 'AddressOf' requires a relaxed conversion
56+
' to the delegate type of the event"
57+
AddHandler ProcessingComplete, AddressOf OnSimpleComplete
58+
59+
' Simulate completion
60+
RaiseEvent ProcessingComplete(Me, EventArgs.Empty)
61+
End Sub
62+
End Class
4863
```
4964

65+
When you compile this code, Visual Basic shows the BC42328 warning for the second `AddHandler` statement because `OnSimpleComplete` doesn't match the `EventHandler` signature exactly.
66+
5067
## Why AddressOf appears to have "no effect"
5168

5269
The warning message states that `AddressOf` "has no effect" because Visual Basic must create a wrapper delegate for the relaxed conversion regardless. The `AddressOf` operator doesn't change how the compiler handles the conversion: the same result occurs whether you use `AddressOf` or not in relaxed conversion scenarios.
@@ -57,36 +74,163 @@ However, `AddressOf` is still syntactically required in `AddHandler` and `Remove
5774

5875
## To correct this error
5976

60-
You have several options depending on your needs:
77+
You have several options depending on your needs. Using the `FileProcessor` example from above, here are the different ways to resolve the BC42328 warning:
6178

62-
- **Assign to a variable first (preserves exact semantics):**
79+
### Option 1: Assign to a variable first (preserves exact semantics)
6380

64-
```vb
65-
Dim handler As EventHandler = AddressOf Handler2
66-
AddHandler SomeEvent, handler
67-
```
81+
```vb
82+
Public Sub StartProcessing()
83+
' Create delegate variable first - this eliminates the warning
84+
Dim handler As EventHandler = AddressOf OnSimpleComplete
85+
AddHandler ProcessingComplete, handler
86+
End Sub
87+
```
6888

69-
- **Match the delegate signature exactly:**
89+
### Option 2: Match the delegate signature exactly
7090

71-
```vb
72-
Sub Handler2(sender As Object, e As EventArgs)
73-
' Implementation - use parameters or ignore them
74-
End Sub
75-
```
91+
```vb
92+
' Change the method signature to match EventHandler exactly
93+
Private Sub OnSimpleComplete(sender As Object, e As EventArgs)
94+
' You can ignore the parameters if you don't need them
95+
Console.WriteLine("Processing is done!")
96+
End Sub
7697

77-
- **Use a lambda expression:**
98+
Public Sub StartProcessing()
99+
' Now this works without warning
100+
AddHandler ProcessingComplete, AddressOf OnSimpleComplete
101+
End Sub
102+
```
78103

79-
```vb
80-
AddHandler SomeEvent, Sub() Handler2()
81-
```
104+
### Option 3: Use a lambda expression
82105

83-
- **Use the `Handles` clause if appropriate:**
106+
```vb
107+
Public Sub StartProcessing()
108+
' Wrap the method call in a lambda that matches the signature
109+
AddHandler ProcessingComplete, Sub(sender, e) OnSimpleComplete()
110+
111+
' Or create a more complex lambda inline
112+
AddHandler ProcessingComplete,
113+
Sub(sender, e)
114+
Console.WriteLine($"Event from {sender}")
115+
OnSimpleComplete()
116+
End Sub
117+
End Sub
118+
```
84119

85-
```vb
86-
Sub Handler2() Handles someObject.SomeEvent
87-
' Implementation
88-
End Sub
89-
```
120+
### Option 4: Use the `Handles` clause (if appropriate)
121+
122+
```vb
123+
Public Class FileProcessor
124+
' Declare the event source with WithEvents
125+
Private WithEvents processor As FileProcessor
126+
127+
' Use Handles clause - no AddHandler needed
128+
Private Sub OnSimpleComplete() Handles processor.ProcessingComplete
129+
Console.WriteLine("Processing is done!")
130+
End Sub
131+
End Class
132+
```
133+
134+
### Option 5: Direct assignment to delegate variable
135+
136+
```vb
137+
Public Sub StartProcessing()
138+
' Assign to delegate variable then use with AddHandler
139+
Dim handler As EventHandler = AddressOf OnSimpleComplete
140+
AddHandler ProcessingComplete, handler
141+
End Sub
142+
```
143+
144+
## Complete working example
145+
146+
Here's a full example demonstrating the warning and multiple solutions:
147+
148+
```vb
149+
Imports System
150+
151+
Public Class DocumentProcessor
152+
' Standard .NET event using EventHandler
153+
Public Event DocumentProcessed As EventHandler
154+
155+
' Custom event with different signature
156+
Public Event StatusChanged As Action(Of String)
157+
158+
' Handlers with different signatures
159+
160+
' Exact match for EventHandler - no warning
161+
Private Sub OnDocumentProcessed_Exact(sender As Object, e As EventArgs)
162+
Console.WriteLine("Document processed (exact signature)")
163+
End Sub
164+
165+
' Simplified handler - causes BC42328 with EventHandler
166+
Private Sub OnDocumentProcessed_Simple()
167+
Console.WriteLine("Document processed (simple)")
168+
End Sub
169+
170+
' Handler for custom event - exact match
171+
Private Sub OnStatusChanged_Exact(message As String)
172+
Console.WriteLine($"Status: {message}")
173+
End Sub
174+
175+
' Handler with ignored parameters - causes BC42328 with custom event
176+
Private Sub OnStatusChanged_Simple()
177+
Console.WriteLine("Status changed")
178+
End Sub
179+
180+
Public Sub DemonstrateWarnings()
181+
Console.WriteLine("Setting up event handlers...")
182+
183+
' These work without warnings (exact matches)
184+
AddHandler DocumentProcessed, AddressOf OnDocumentProcessed_Exact
185+
AddHandler StatusChanged, AddressOf OnStatusChanged_Exact
186+
187+
' These generate BC42328 warnings (relaxed conversions)
188+
AddHandler DocumentProcessed, AddressOf OnDocumentProcessed_Simple
189+
AddHandler StatusChanged, AddressOf OnStatusChanged_Simple
190+
191+
' Fire the events
192+
RaiseEvent DocumentProcessed(Me, EventArgs.Empty)
193+
RaiseEvent StatusChanged("Processing complete")
194+
End Sub
195+
196+
Public Sub DemonstrateSolutions()
197+
Console.WriteLine("Using solutions to avoid warnings...")
198+
199+
' Solution 1: Assign to variable first
200+
Dim handler1 As EventHandler = AddressOf OnDocumentProcessed_Simple
201+
AddHandler DocumentProcessed, handler1
202+
203+
' Solution 2: Use lambda expression
204+
AddHandler DocumentProcessed, Sub(s, e) OnDocumentProcessed_Simple()
205+
206+
' Solution 3: Direct assignment to delegate variable
207+
Dim handler2 As Action(Of String) = AddressOf OnStatusChanged_Simple
208+
AddHandler StatusChanged, handler2
209+
210+
' Fire the events
211+
RaiseEvent DocumentProcessed(Me, EventArgs.Empty)
212+
RaiseEvent StatusChanged("All solutions work")
213+
End Sub
214+
End Class
215+
216+
Module Program
217+
Sub Main()
218+
Dim processor As New DocumentProcessor()
219+
220+
Console.WriteLine("=== Demonstrating BC42328 Warning ===")
221+
processor.DemonstrateWarnings()
222+
223+
Console.WriteLine()
224+
Console.WriteLine("=== Demonstrating Solutions ===")
225+
processor.DemonstrateSolutions()
226+
227+
Console.WriteLine("Press any key to exit...")
228+
Console.ReadKey()
229+
End Sub
230+
End Module
231+
```
232+
233+
This example shows how the warning occurs in realistic scenarios and demonstrates multiple ways to resolve it.
90234

91235
## When you can ignore this warning
92236

@@ -95,8 +239,27 @@ This warning is often safe to ignore when:
95239
- Your handler method intentionally omits parameters it doesn't need.
96240
- You're using a simpler method signature for cleaner code.
97241
- The performance impact is negligible for your application.
242+
- You're prototyping or writing quick utility code where clarity matters more than efficiency.
98243

99-
The relaxed conversion works correctly; this warning just indicates a minor efficiency consideration.
244+
The relaxed conversion works correctly; this warning just indicates a minor efficiency consideration. The compiler creates a wrapper delegate automatically, which adds a small performance overhead but doesn't affect functionality.
245+
246+
### Example of when ignoring is appropriate
247+
248+
```vb
249+
Public Class QuickLogger
250+
Public Event LogMessage As Action(Of String, DateTime)
251+
252+
' Simple handler that ignores the timestamp parameter
253+
Private Sub WriteToConsole()
254+
Console.WriteLine("Something was logged")
255+
End Sub
256+
257+
Public Sub SetupLogging()
258+
' This generates BC42328, but it's fine for simple scenarios
259+
AddHandler LogMessage, AddressOf WriteToConsole
260+
End Sub
261+
End Class
262+
```
100263

101264
## See also
102265

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
Imports System
2+
3+
Public Class DocumentProcessor
4+
' Standard .NET event using EventHandler
5+
Public Event DocumentProcessed As EventHandler
6+
7+
' Custom event with different signature
8+
Public Event StatusChanged As Action(Of String)
9+
10+
' Handlers with different signatures
11+
12+
' Exact match for EventHandler - no warning
13+
Private Sub OnDocumentProcessed_Exact(sender As Object, e As EventArgs)
14+
Console.WriteLine("Document processed (exact signature)")
15+
End Sub
16+
17+
' Simplified handler - causes BC42328 with EventHandler
18+
Private Sub OnDocumentProcessed_Simple()
19+
Console.WriteLine("Document processed (simple)")
20+
End Sub
21+
22+
' Handler for custom event - exact match
23+
Private Sub OnStatusChanged_Exact(message As String)
24+
Console.WriteLine($"Status: {message}")
25+
End Sub
26+
27+
' Handler with ignored parameters - causes BC42328 with custom event
28+
Private Sub OnStatusChanged_Simple()
29+
Console.WriteLine("Status changed")
30+
End Sub
31+
32+
Public Sub DemonstrateWarnings()
33+
Console.WriteLine("Setting up event handlers...")
34+
35+
' These work without warnings (exact matches)
36+
AddHandler DocumentProcessed, AddressOf OnDocumentProcessed_Exact
37+
AddHandler StatusChanged, AddressOf OnStatusChanged_Exact
38+
39+
' These generate BC42328 warnings (relaxed conversions)
40+
AddHandler DocumentProcessed, AddressOf OnDocumentProcessed_Simple
41+
AddHandler StatusChanged, AddressOf OnStatusChanged_Simple
42+
43+
' Fire the events
44+
RaiseEvent DocumentProcessed(Me, EventArgs.Empty)
45+
RaiseEvent StatusChanged("Processing complete")
46+
End Sub
47+
48+
Public Sub DemonstrateSolutions()
49+
Console.WriteLine("Using solutions to avoid warnings...")
50+
51+
' Solution 1: Assign to variable first
52+
Dim handler1 As EventHandler = AddressOf OnDocumentProcessed_Simple
53+
AddHandler DocumentProcessed, handler1
54+
55+
' Solution 2: Use lambda expression
56+
AddHandler DocumentProcessed, Sub(s, e) OnDocumentProcessed_Simple()
57+
58+
' Solution 3: Direct assignment to delegate variable
59+
Dim handler2 As Action(Of String) = AddressOf OnStatusChanged_Simple
60+
AddHandler StatusChanged, handler2
61+
62+
' Fire the events
63+
RaiseEvent DocumentProcessed(Me, EventArgs.Empty)
64+
RaiseEvent StatusChanged("All solutions work")
65+
End Sub
66+
End Class
67+
68+
Module Program
69+
Sub Main()
70+
Dim processor As New DocumentProcessor()
71+
72+
Console.WriteLine("=== Demonstrating BC42328 Warning ===")
73+
processor.DemonstrateWarnings()
74+
75+
Console.WriteLine()
76+
Console.WriteLine("=== Demonstrating Solutions ===")
77+
processor.DemonstrateSolutions()
78+
79+
Console.WriteLine("Press any key to exit...")
80+
Console.ReadKey()
81+
End Sub
82+
End Module
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<RootNamespace>BC42328Example</RootNamespace>
7+
</PropertyGroup>
8+
9+
</Project>

0 commit comments

Comments
 (0)