# Source Generated Classes and Nullability in Realm .NET

The latest releases of Realm .NET have included some interesting updates that we would love to share — in particular, source generated classes and support for nullability annotation. 

## Source generated classes

Realm 10.18.0 introduced `Realm.SourceGenerator`, a source generator that can generate Realm model classes. This is part of our ongoing effort to modernize the Realm library, and will allow us to introduce certain language level features more easily in the future.

The migration to the new source generated classes is quite straightforward. All you need to do is:

* Declare the Realm classes as `partial`, including all the eventual containing classes.
* Swap out the base Realm classes (`RealmObject`, `EmbeddedObject`, `AsymmetricObject`) for the equivalent interfaces (`IRealmObject`, `IEmbeddedObject`, `IAsymmetricObject`).
* Declare `OnManaged` and `OnPropertyChanged` methods as `partial` instead of overriding them, if they are used.

The property definition remains the same, and the source generator will take care of adding the full implementation of the interfaces. 

To give an example, if your model definition looks like this:

```csharp
public class Person: RealmObject
{
    public string Name { get; set; }  

    public PhoneNumber Phone { get; set; }

    protected override void OnManaged()
    {
        //...
    }

    protected override void OnPropertyChanged(string propertyName)
    {
        //...
    } 
}

public class PhoneNumber: EmbeddedObject
{
    public string Number { get; set; }

    public string Prefix { get; set; }  
}
```
This is how it should look like after you migrated it: 

```csharp
public partial class Person: IRealmObject
{
    public string Name { get; set; }  

    public PhoneNumber Phone { get; set; }

    partial void OnManaged()
    {
        //...
    }

    partial void OnPropertyChanged(string propertyName)
    {
        //...
    } 
}

public partial class PhoneNumber: IEmbeddedObject
{
    public string Number { get; set; }

    public string Prefix { get; set; }  
}
```
The classic Realm model definition is still supported, but it will not receive some of the new updates, such as the support for nullability annotations, and will be phased out in the future. 

## Nullability annotations

Realm 10.20.0 introduced full support for nullability annotations in the model definition for source generated classes. This allows you to use Realm models as usual when nullable context is active, and removes the need to use the `Required` attribute to indicate required properties, as this information will be inferred directly from the nullability status.

To sum up the expected nullability annotations:
* Value type properties, such as `int`, can be declared as before, either nullable or not.
* `string` and `byte]` properties now cannot be decorated anymore with the `Required` attribute, as this information will be inferred from the nullability. If the property is not nullable, then it is considered equivalent as declaring it with the `Required` attribute.
* Collections (list, sets, dictionaries, and backlinks) cannot be declared nullable, but their parameters may be.
* Properties that link to a single Realm object are inherently nullable, and thus the type must be defined as nullable.
* Lists, sets, and backlinks of objects cannot contain null values, and thus the type parameter must be non-nullable.
* Dictionaries of object values can contain null, and thus the type parameter must be nullable.

Defining the properties with a different nullability annotation than what has been outlined will raise a diagnostic error. For instance:
  ```cs
public partial class Person: IRealmObject
{
    //string (same for byte[])
    public string Name { get; set; } //Correct, required property

    public string? Name { get; set; } //Correct, non-required property

    //Collections
    public IList IntList { get; } //Correct

    public IList IntList { get; } //Correct

    public IList? IntList { get; } //Error

    //Object 
    public Dog? MyDog { get; set; } //Correct

    public Dog MyDog { get; set; } //Error

    //List of objects
    public IList MyDogs { get; } //Correct

    public IList MyDogs { get; } //Error

    //Set of objects
    public ISet MyDogs { get; } //Correct

    public ISet MyDogs { get; } //Error

    //Dictionary of objects
    public IDictionary MyDogs { get; } //Correct

    public IDictionary MyDogs { get; } //Error

    //Backlink
    [Realms.Backlink("...")]
    public IQueryable MyDogs { get; } //Correct

    [Realms.Backlink("...")]
    public IQueryable MyDogs { get; } //Error
}
  ```

We realize that some developers would prefer to have more freedom in the nullability annotation of object properties, and it is possible to do so by setting `realm.ignore_objects_nullability = true` in a global configuration file (more information about this can be found in the [.NET documentation). If this option is enabled, all the object properties (including collections) will be considered valid, and the nullability annotations will be ignored.

Finally, please note that this will only work with source generated classes, and not with the classic Realm model definition. If you want more information, you can take a look at the Realm .NET repository and at our documentation.

Want to continue the conversation? Head over to our community forums!