<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/annotating-your-c-code---migrating-to-nullable-reference-types---part-3-fgixi3ipo" -->

---
title: Annotating your C# code - Migrating to nullable...
description: This third installment in a C# nullable reference types migration series covers the attributes available in System.Diagnostics.CodeAnalysis to help the...
canonical: https://daily.dev/posts/annotating-your-c-code---migrating-to-nullable-reference-types---part-3-fgixi3ipo
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Annotating your C# code - Migrating to nullable reference types - Part 3 | daily.dev
og:description: This third installment in a C# nullable reference types migration series covers the attributes available in System.Diagnostics.CodeAnalysis to help the...
og:url: https://daily.dev/posts/annotating-your-c-code---migrating-to-nullable-reference-types---part-3-fgixi3ipo
og:image: https://api.daily.dev/og/posts/FGIxI3IPo.png
og:image:alt: Annotating your C# code - Migrating to nullable reference types - Part 3
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Annotating your C# code - Migrating to nullable reference types - Part 3

**[Maarten Balliauw](https://daily.dev/sources/maartenballiauw)** · 13 min read · 0 upvotes · 0 comments

## Summary

This third installment in a C# nullable reference types migration series covers the attributes available in System.Diagnostics.CodeAnalysis to help the compiler's flow analysis understand nullability beyond the basic `?` annotation. It explains NotNullIfNotNull, NotNullWhen, AllowNull, DisallowNull, MaybeNull, NotNull, MemberNotNull, MemberNotNullWhen, DoesNotReturn, and DoesNotReturnIf, with code examples for preconditions, post-conditions, conditional post-conditions, helper methods, and failure conditions. It also covers JetBrains Annotations (CanBeNull, NotNull, ContractAnnotation) as a pre-C#8 alternative still useful with ReSharper/Rider, nullability with generics (MaybeNull on generic methods, the notnull constraint), the state of annotations in .NET 6 framework code, and the reminder that nullable reference types are compile-time only with no runtime enforcement, so null checks are still required.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://blog.maartenballiauw.be/posts/2022-04-25-annotating-your-csharp-code-migrating-to-nullable-reference-types-part-3>

## Questions this post answers

### How do I tell the C# compiler that a method's return value is not null when the input argument is not null?

Use the NotNullIfNotNull attribute on the return value, naming the parameter it depends on, for example [return: NotNullIfNotNull("value")] above a method signature like string? Slugify(string? value). This tells flow analysis that if the named argument is non-null, the return value is also guaranteed non-null, removing unnecessary dereference warnings like CS8602.

_daily.dev surfaces walkthroughs like this for developers tightening up nullability annotations in C# projects._

### How do I stop the C# compiler from warning about a non-nullable field not being initialized in the constructor when I set it in a separate helper method?

Add the MemberNotNull attribute to the helper method, naming the field it initializes, for example [MemberNotNull(nameof(_id))] on a private EnsureIdentifier() method called from the constructor. This tells the compiler that calling that method guarantees the field is non-null afterward, resolving warning CS8618 about non-nullable fields being null when exiting the constructor.

_developers wiring up nullable reference types can track patterns like this via daily.dev when refactoring constructors._

### What is the JetBrains ContractAnnotation attribute and how does it differ from C#'s own nullable attributes?

ContractAnnotation is a JetBrains Annotations attribute that describes input/output null conditions in one declarative string, for example [ContractAnnotation("json:null => false,person:null")] meaning a null json argument causes the method to return false with person set to null. It follows natural input-to-output flow, unlike C#'s NotNullWhen which states things backward (output false implies input was null), and still works with ReSharper/Rider even though the C# compiler itself does not recognize it.

_daily.dev helps C# developers comparing JetBrains Annotations against native nullable attributes before standardizing on one approach._

## Similar posts on daily.dev

- [Taming the Billion Dollar Mistake: Maarten Balliauw's Guide to C\# Nullable Reference Types](https://daily.dev/posts/taming-the-billion-dollar-mistake-maarten-balliauw-s-guide-to-c-nullable-reference-types-dhuc5b5o7) · JetBrains · 5 upvotes · 0 comments
- [Micronaut 5 adoption of the JSpecify nullability annotations](https://daily.dev/posts/micronaut-5-adoption-of-the-jspecify-nullability-annotations-jhrgtm2a1) · Micronaut Framework · 9 upvotes · 0 comments
- [One Could Simply Add Nullability Check Support… Without Even Noticing It](https://daily.dev/posts/one-could-simply-add-nullability-check-support-without-even-noticing-it-t5jmmum79) · JetBrains · 7 upvotes · 0 comments

---

Tags: [#devtools](https://daily.dev/tags/devtools), [#.net](https://daily.dev/tags/.net), [#c#](https://daily.dev/tags/c#)

[View this post on daily.dev](https://daily.dev/posts/annotating-your-c-code---migrating-to-nullable-reference-types---part-3-fgixi3ipo)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Annotating your C# code - Migrating to nullable reference types - Part 3","url":"https://daily.dev/posts/annotating-your-c-code---migrating-to-nullable-reference-types---part-3-fgixi3ipo","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/annotating-your-c-code---migrating-to-nullable-reference-types---part-3-fgixi3ipo"},"datePublished":"2026-10-04T13:04:27.257Z","dateModified":"2026-10-04T13:07:03.127Z","description":"This third installment in a C# nullable reference types migration series covers the attributes available in System.Diagnostics.CodeAnalysis to help the...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/10309805b0e0575172aef3ea9763ab63?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/10309805b0e0575172aef3ea9763ab63?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Maarten Balliauw","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Maarten Balliauw","logo":"https://media.daily.dev/image/upload/s--rOTg3VYO--/f_auto,q_auto/v1791119043/logos/maartenballiauw?_a=BAMAMicg0","url":"https://daily.dev/sources/maartenballiauw"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/annotating-your-c-code---migrating-to-nullable-reference-types---part-3-fgixi3ipo","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"devtools,.net,c#","timeRequired":"PT13M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Maarten Balliauw","item":"https://daily.dev/sources/maartenballiauw"},{"@type":"ListItem","position":3,"name":"Annotating your C# code - Migrating to nullable reference types - Part 3"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/annotating-your-c-code---migrating-to-nullable-reference-types---part-3-fgixi3ipo#faq","mainEntity":[{"@type":"Question","name":"How do I tell the C# compiler that a method's return value is not null when the input argument is not null?","acceptedAnswer":{"@type":"Answer","text":"Use the NotNullIfNotNull attribute on the return value, naming the parameter it depends on, for example [return: NotNullIfNotNull(\"value\")] above a method signature like string? Slugify(string? value). This tells flow analysis that if the named argument is non-null, the return value is also guaranteed non-null, removing unnecessary dereference warnings like CS8602. daily.dev surfaces walkthroughs like this for developers tightening up nullability annotations in C# projects."}},{"@type":"Question","name":"How do I stop the C# compiler from warning about a non-nullable field not being initialized in the constructor when I set it in a separate helper method?","acceptedAnswer":{"@type":"Answer","text":"Add the MemberNotNull attribute to the helper method, naming the field it initializes, for example [MemberNotNull(nameof(_id))] on a private EnsureIdentifier() method called from the constructor. This tells the compiler that calling that method guarantees the field is non-null afterward, resolving warning CS8618 about non-nullable fields being null when exiting the constructor. developers wiring up nullable reference types can track patterns like this via daily.dev when refactoring constructors."}},{"@type":"Question","name":"What is the JetBrains ContractAnnotation attribute and how does it differ from C#'s own nullable attributes?","acceptedAnswer":{"@type":"Answer","text":"ContractAnnotation is a JetBrains Annotations attribute that describes input/output null conditions in one declarative string, for example [ContractAnnotation(\"json:null => false,person:null\")] meaning a null json argument causes the method to return false with person set to null. It follows natural input-to-output flow, unlike C#'s NotNullWhen which states things backward (output false implies input was null), and still works with ReSharper/Rider even though the C# compiler itself does not recognize it. daily.dev helps C# developers comparing JetBrains Annotations against native nullable attributes before standardizing on one approach."}}]}
```

