/StrictNulls

StrictNulls is a C# Source Generator that adds null guards for all non-nullable reference type parameters.

Primary LanguageC#Apache License 2.0Apache-2.0

QuickConstructor

QuickConstructor

QuickConstructor is a reliable and feature-rich source generator that can automatically emit a constructor from the fields and properties of a class.

Features

  • Decorate any class with the [QuickConstructor] attribute to automatically generate a constructor for that class.
  • The constructor updates in real-time as the class is modified.
  • Customize which fields and properties are initialized in the constructor.
  • Generate null checks automatically based on nullable annotations.
  • Works with nested classes and generic classes.
  • Supports derived classes.
  • Supports classes, records and structs.
  • Ability to place attributes on the parameters of the generated constructor.
  • No traces left after compilation, no runtime reference necessary.
  • Generate XML documentation automatically for the constructor.
  • Lightning fast thanks to the .NET 6.0 incremental source generator system.

Example

Code without QuickConstructor:

public class Car
{
    private readonly string _registration;
    private readonly string _model;
    private readonly string _make;
    private readonly string _color;
    private readonly int _year;

    public Car(string registration, string model, string make, string color, int year)
    {
        _registration = registration;
        _model = model;
        _make = make;
        _color = color;
        _year = year;
    }
}

With QuickConstructor, this becomes:

[QuickConstructor]
public partial class Car
{
    private readonly string _registration;
    private readonly string _model;
    private readonly string _make;
    private readonly string _color;
    private readonly int _year;
}

The constructor is automatically generated from the field definitions.

Installation

The requirements to use the QuickConstructor package are the following:

  • Visual Studio 17.0+
  • .NET SDK 6.0.100+

Install the NuGet package:

dotnet add package QuickConstructor

Usage

QuickConstructor is very easy to use. By simply decorating a class with the [QuickConstructor] attribute and making the class partial, the source generator will automatically create a constructor based on fields and properties declared in the class. The constructor will automatically update to reflect any change made to the class.

QuickConstructor offers options to customize various aspects of the constructors being generated.

Fields selection

Quick constructors will always initialize read-only fields as the constructor would otherwise cause a compilation error. However mutable fields can either be included or excluded from the constructor. This is controlled via the Fields property of the [QuickConstructor] attribute. The possible values are:

Value Description
IncludeFields.ReadOnlyFields (default) Only read-only fields are initialized in the constructor.
IncludeFields.AllFields All fields are initialized in the constructor.

Fields with an initializer are never included as part of the constructor.

Properties selection

It is possible to control which property is initialized in the constructor via the Properties property of the [QuickConstructor] attribute. The possible values are:

Value Description
IncludeProperties.None No property is initialized in the constructor.
IncludeProperties.ReadOnlyProperties (default) Only read-only auto-implemented properties are initialized in the constructor.
IncludeProperties.AllProperties All settable properties are initialized in the constructor.

Properties with an initializer are never included as part of the constructor.

Null checks

QuickConstructor has the ability to generate null checks for reference parameters. This is controlled via the NullCheck property of the [QuickConstructor] attribute. The possible values are:

Value Description
NullChecks.Always Null checks are generated for any field or property whose type is a reference type.
NullChecks.Never Null checks are not generated for this constructor.
NullChecks.NonNullableReferencesOnly (default) When null-state analysis is enabled (C# 8.0 and later), a null check will be generated only if a type is marked as non-nullable. When null-state analysis is disabled, no null check is generated.

For example, with null-state analysis enabled:

[QuickConstructor]
public partial class Name
{
    private readonly string _firstName;
    private readonly string? _middleName;
    private readonly string _lastName;
}

This code will result in the following constructor being generated:

public Name(string firstName, string? middleName, string lastName)
{
    if (firstName == null)
        throw new ArgumentNullException(nameof(firstName));

    if (lastName == null)
        throw new ArgumentNullException(nameof(lastName));

    this._firstName = firstName;
    this._middleName = middleName;
    this._lastName = lastName;
}

Explicitely include a field or property

It is possible to explicitely include a field or property by decorating it with the [QuickConstructorParameter].

For example:

[QuickConstructor]
public partial class Vehicle
{
    [QuickConstructorParameter]
    private int _mileage;

    private int _speed;
}

will result in this constructor:

public Vehicle(int mileage)
{
    this._mileage = mileage;
}

While both _mileage and _speed are mutable fields, and therefore are exluded by default, _mileage does get initialized in the constructor because it is decorated with [QuickConstructorParameter].

Overriding the name of a parameter

It is possible to override the name of a parameter in the constructor using the Name property of the [QuickConstructorParameter] attribute.

This class:

[QuickConstructor]
public partial class Vehicle
{
    [QuickConstructorParameter(Name = "startingMileage")]
    private int _mileage;

    private int _speed;
}

will result in this constructor:

public Vehicle(int startingMileage)
{
    this._mileage = startingMileage;
}

Derived classes

It is possible to generate a constructor for a class inheriting from a base class, however the base class must either itself be decorated with [QuickConstructor], or it must have a parameterless constructor.

For example:

[QuickConstructor(Fields = IncludeFields.AllFields)]
public partial class Vehicle
{
    private int _mileage;
    private int _speed;
}

[QuickConstructor]
public partial class Bus : Vehicle
{
    private readonly int _capacity;
}

In that situation, a constructor will be generated for the Bus class, with the following implementation:

public Bus(int mileage, int speed, int capacity)
    : base(mileage, speed)
{
    this._capacity = capacity;
}

Constructor accessibility

It is possible to customize the accessibility level of the auto-generated constructor. This is controlled via the ConstructorAccessibility property of the [QuickConstructor] attribute.

License

Copyright 2022 Flavien Charlon

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.