Nullable value types in C# attributes

November 18th 2022 C#

Attributes in C# support only a limited number of parameter types. If you want to use other types, such as Nullable<int>, you must find a way around this limitation.

Attribute classes can have properties of other types:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class MyAttribute : Attribute
{
    public int? NullableParameter { get; set; }
}

But you cannot set them for an attribute instance:

[My(NullableParameter = 1)]
public record MyRecord();

The compiler complains with the following error message:

CS0655: NullableParameter is not a valid named attribute argument because it is not a valid attribute parameter type

You could try to add a constructor with an optional parameter to the attribute class:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class MyAttribute : Attribute
{
    public MyAttribute(int? nullableParameter = null)
    {
        NullableParameter = nullableParameter;
    }

    public int? NullableParameter { get; set; }
}

But the compiler will not allow you to use this constructor:

[My(nullableParameter: 1)]
public record MyRecord();

It will complain with a slightly different error message:

CS0181: Attribute constructor parameter nullableParameter has type int?, which is not a valid attribute parameter type

Instead of adding a constructor with an optional parameter of type Nullable<int>, you can add two constructors to achieve the same thing without using the unsupported type Nullable<int>:

public class MyAttribute : Attribute
{
    public MyAttribute() { }

    public MyAttribute(int nullableParameter)
    {
        NullableParameter = nullableParameter;
    }

    public int? NullableParameter { get; set; }
}

The compiler allows you to use these two constructors because they have no parameters of unsupported types:

[My()]
[My(nullableParameter: 1)]
public record MyRecord();

I have put an example project with this approach in my GitHub repository.

Attributes in C# have many limitations, but with creativity you can work around some of them. In this post, I described a possible approach to using nullable value types.

Get notified when a new blog post is published (usually every Friday):

If you're looking for online one-on-one mentorship on a related topic, you can find me on Codementor.
If you need a team of experienced software engineers to help you with a project, contact us at Razum.
Copyright
Creative Commons License