C# 14 introduces null-conditional assignment (?.=), a small but highly practical language enhancement that reduces repetitive null checks when updating objects. It builds on the existing null-conditional operator (?.) and allows assignments to occur only when the target object is not null.
This feature improves code readability, reduces boilerplate, and helps prevent NullReferenceException in real-world applications where optional objects are common.
What Is Null-Conditional Assignment (?.=)?
Assigns a value only if the target object is not null
Skips the assignment silently when the target is null
Prevents NullReferenceException
Works with fields and properties
Designed for defensive and optional updates
Syntax
target?.Property = value;
Before C# 14: How Null Checks Were Handled
Manual Null Check
if (user != null)
{
user.IsActive = true;
}
Null-Conditional Operator (Read-Only)
user?.Activate();
Works for method calls and reads
Does not support assignment
Still requires explicit checks for updates
C# 14 Null-Conditional Assignment in Action
user?.IsActive = true;
Real-Life Scenarios
1.Optional Logging Service
logger?.LastMessage = "Order processed successfully";
Logging may be disabled in some environments
Business logic remains unaffected
Eliminates unnecessary branching
2. UI or ViewModel Updates
viewModel?.StatusMessage = "Loading completed";
UI elements may not yet be initialized
Common in MVVM, desktop, and mobile apps
Prevents runtime crashes
3. Cache Metadata Updates
cacheEntry?.LastAccessed = DateTime.UtcNow;
Cache entries may expire or be unavailable
Keeps caching logic concise
Improves application stability
Complex Scenarios
1. Order Processing with Optional Audit Trail
public void CompleteOrder(Order order, AuditTrail audit)
{
order.Status = OrderStatus.Completed;
order.CompletedAt = DateTime.UtcNow;
audit?.LastAction = "Order completed";
audit?.UpdatedAt = DateTime.UtcNow;
}
Order completion is mandatory
Audit tracking is optional
Keeps core business logic clean
2. Middleware with Optional Telemetry
public async Task InvokeAsync(HttpContext context, Telemetry telemetry)
{
var start = DateTime.UtcNow;
await _next(context);
telemetry?.RequestPath = context.Request.Path;
telemetry?.DurationMs =
(DateTime.UtcNow - start).TotalMilliseconds;
}
Telemetry may be disabled for performance
Avoids cluttering middleware code
Maintains clear execution flow
3. Async Service with Optional Cache Sync
public async Task<UserProfile> GetProfileAsync(
int userId,
IProfileCache cache)
{
var profile = await LoadFromDatabaseAsync(userId);
cache?.Profile = profile;
cache?.LastRefresh = DateTime.UtcNow;
return profile;
}
Database remains the source of truth
Cache is an optional optimization
Clean separation of concerns
4. Plugin-Based Application
public void Initialize(App app, IPluginContext pluginContext)
{
app.Start();
pluginContext?.State = PluginState.Initialized;
pluginContext?.InitializedAt = DateTime.UtcNow;
}
Plugins may or may not be installed
Core app logic is unaffected
Safer extensibility model
Comparison: Before vs C# 14
| Aspect | Before C# 14 | C# 14 with ?.= |
|---|
| Null handling | Manual checks | Built-in |
| Code verbosity | Higher | Lower |
| Readability | Moderate | High |
| Risk of null exceptions | Higher | Reduced |
| Intent clarity | Less explicit | Clear |
Decision Guide: When to Use or Avoid ?.=
| Question | Use ?.= | Avoid ?.= |
|---|
| Is the object optional? | Yes | No |
| Is the assignment non-critical? | Yes | No |
| Is skipping the assignment acceptable? | Yes | No |
| Does null indicate a valid state? | Yes | No |
| Is this logging, telemetry, caching, UI state? | Yes | No |
| Is this core business logic? | No | Yes |
When to Use Null-Conditional Assignment
Optional dependencies
Logging, telemetry, metrics
UI or view-model updates
Caching and configuration
Plugin and extension systems
Defensive programming in large systems
When Not to Use Null-Conditional Assignment
Core domain state changes
When null represents a bug
When assignment must always occur
Critical business rules
Scenarios requiring explicit error handling
Example to avoid
order?.Status = OrderStatus.Completed;
Performance Considerations
No runtime performance overhead
Compiles to efficient null checks
Equivalent to manually written if (x != null) logic
Improves maintainability without affecting execution speed
Benefits Summary
Conclusion
Null-conditional assignment in C# 14 provides a concise and expressive way to handle optional object updates. It reduces repetitive null checks while maintaining performance and clarity. When used for auxiliary and defensive updates, it leads to cleaner, safer, and more maintainable code. Used thoughtfully, ?.= becomes a valuable addition to modern C# development.
Happy Coding!