'Use non-nullable reference types in DTO:s/api objects

I want to use non-nullable reference type in my dto:s/api objects, without getting warnings and without defeating the entire purpose by using them by using the bang operator.

Lets say I consume from an GraphQL-endpoints that returns a hierarchy of complex objects. So normally I just deserialize the response with a type parameter...something like this

var customerInfo = mySerializer.Deserialize<CustomerInfo>(jsonResponseFromServer)

From the schema-file I have a guarantee that some of these objects and strings (inside CustomerInfo) are not null.

so I want to use non-nullable reference types in my DTOs. But now I get complaints about all these non-nullable properties, because the compiler has no clue about the GraphQL-scheme.

I'd really want to avoid writing humongous constructor for all these objects and If I did I wouldn't know how to get my serializer to use those anyway...

This must be a quite common problem, but I haven't found any recommended solution

Edit, from a comment: about the structure of my class, lets keep it simple, because the exact structure is not relevant

public class CustomerInfo
{
    public string Name {get;set;}
    public Address Address {get;set;}
    //...  
}

So...nothing special.



Solution 1:[1]

Non-nullable reference type is a syntactic addition which is only used in static code analysis, where compiler tries to prove that a null assignment is not attempted on a reference.

As mentioned in the comment, this has nothing to do with the GraphQL, nor with deserialization. It is entirely a C# question.

Another related issue is that there is no runtime check whether a null reference is assigned or not. Therefore, my first concern is in using non-nullable reference types in a DTO in the first place - what is the purpose of that if, at runtime, that reference can be set to null none the less, probably causing a NullReferenceException downstream that was not supposed to happen.

And, finally, the direct answer to the question. If a type declares fields or properties of non-nullable types, then for each of those, one of these must be present in code to avoid warnings:

  1. Set to a non-null value in the constructor,
  2. Initialized to a non-null value using the initializer syntax, or
  3. Initialized to a null! to mark the intention to set to a non-null value later.

Regarding your particular design with DTOs, be warned that any non-nullable reference type could effectively be set to null later, should the data you are deserializing change in the future. You should still provide a constructor which guards against null inputs.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1