If you’ve enabled nullable annotations in C#, you’ve probably seen CS8602 and CS8603 warnings.
Some of these warnings are helpful for finding possible null-reference errors. But in more complex methods, the compiler can’t always understand your custom checks. It still thinks values might be null, even when you’ve already checked them.
Attributes from System.Diagnostics.CodeAnalysis let you describe method contracts explicitly and remove that noise.
A Simple Try* Example
Before: Noisy Warnings
bool TryGetDomain(string? url, out string? domain)
{
if (url is null || !url.Contains("://"))
{
domain = null;
return false;
}
domain = url.Split("://")[1];
return true; // domain is not null here
}
if (TryGetDomain(link, out var d))
{
Console.WriteLine(d.Length); // CS8602: Possible null reference
}
The compiler sees that domain is declared nullable and assumes it might be null even when the method returns true.
After: Explicit Contract, No Noise
using System.Diagnostics.CodeAnalysis;
bool TryGetDomain(
string? url,
[NotNullWhen(true)] out string? domain)
{
if (url is null || !url.Contains("://"))
{
domain = null;
return false; // null is allowed when we return false
}
domain = url.Split("://")[1];
return true; // null is impossible when we return true
}
if (TryGetDomain(link, out var d))
{
Console.WriteLine(d.Length); // No warning
}
[NotNullWhen(true)] tells the analyzer: “If the method returns true, the out parameter is never null.”
The result is cleaner call sites with fewer manual checks.
Why Bother?
-
Fewer null checks. Your code stays leaner.
-
Contracts in the signature. Behavior is easier to understand during reading and code review.
-
More accurate static analysis. The compiler can focus on real issues.
Other Attributes Worth Knowing
-
[MaybeNullWhen(true)]indicates that anoutorrefparameter may benullwhen the method returnstrue. -
[NotNullIfNotNull("param")]indicates that the return value won’t benullwhen the specified input parameter isn’tnull. -
[MemberNotNull("Field")]indicates that a method guarantees a field or property is initialized before it exits. -
[DoesNotReturnIf(true)]indicates that a method never returns when the annotated Boolean parameter istrue, typically because it throws an exception.
How to Start
In .NET 5 and later, these attributes are built in.
Add them to methods whose behavior matches the contracts described above. This gives the compiler more context while keeping the runtime behavior unchanged.