|
| 1 | +# EPC16 - Awaiting a result of a null-conditional expression will cause NullReferenceException |
| 2 | + |
| 3 | +This analyzer detects dangerous patterns where awaiting the result of a null-conditional operator can cause a `NullReferenceException`. |
| 4 | + |
| 5 | +## Description |
| 6 | + |
| 7 | +The analyzer warns when code awaits the result of a null-conditional expression. When the left-hand side of the null-conditional operator is null, the expression returns null, and awaiting null will throw a `NullReferenceException`. |
| 8 | + |
| 9 | +## Code that triggers the analyzer |
| 10 | + |
| 11 | +```csharp |
| 12 | +public async Task ProcessAsync() |
| 13 | +{ |
| 14 | + SomeService service = GetService(); // might return null |
| 15 | + |
| 16 | + // Dangerous: if service is null, this returns null, and awaiting null throws NRE |
| 17 | + await service?.ProcessAsync(); |
| 18 | +} |
| 19 | +``` |
| 20 | + |
| 21 | +```csharp |
| 22 | +public async Task<string> GetDataAsync() |
| 23 | +{ |
| 24 | + var client = GetHttpClient(); // might return null |
| 25 | + |
| 26 | + // This will throw NRE if client is null |
| 27 | + return await client?.GetStringAsync("http://example.com"); |
| 28 | +} |
| 29 | +``` |
| 30 | + |
| 31 | +## How to fix |
| 32 | + |
| 33 | +Check for null before awaiting, or use proper null handling: |
| 34 | + |
| 35 | +```csharp |
| 36 | +public async Task ProcessAsync() |
| 37 | +{ |
| 38 | + SomeService service = GetService(); |
| 39 | + |
| 40 | + // Option 1: Check for null first |
| 41 | + if (service != null) |
| 42 | + { |
| 43 | + await service.ProcessAsync(); |
| 44 | + } |
| 45 | + |
| 46 | + // Option 2: Use null-coalescing with Task.CompletedTask |
| 47 | + await (service?.ProcessAsync() ?? Task.CompletedTask); |
| 48 | +} |
| 49 | +``` |
| 50 | + |
| 51 | +```csharp |
| 52 | +public async Task<string> GetDataAsync() |
| 53 | +{ |
| 54 | + var client = GetHttpClient(); |
| 55 | + |
| 56 | + // Check for null before using |
| 57 | + if (client == null) |
| 58 | + { |
| 59 | + return null; // or throw, or return default value |
| 60 | + } |
| 61 | + |
| 62 | + return await client.GetStringAsync("http://example.com"); |
| 63 | +} |
| 64 | +``` |
0 commit comments