Avoid generic attributes for .NET targets without support for it

Since C# 11, generic attributes are supported. This is a powerful feature that can improve the usage of attributes. For example:

class MyModel
{
    [MinValue<int>(42)]
    public int Value { get; init; }
}

As it is a language feature, that also allows the usage for any .NET target as long as the language version is at least C# 11. Unfortunately, this can lead to runtime issues. In the given example if I run typeof(MyModel).GetCustomAttributes() for .NET 4.8 (some people still have to deal with this) the call crashes, explicitly stating that generic types are not supported.

So this rule should be triggered for all .NET framework (classic) targets, and all .netstandard targets. I did not test (yet) if there are older .NET Core targets that would lead to runtime crashes.

Noncompliant

[SomeGeneric<NonCompliant>] // Non-compliant {{Generic attributes are not supported 
by the net4.8 runtime}}
class NonCompliant
{
    public NonCompliant([SomeGeneric<int>] int value) // Non-compliant
    //                   ^^^^^^^^^^^^^^^^
    {
        Property = value;
    }

    [SomeGeneric<int>] // Non-compliant
    int Property { get; set; }
}

Noncompliant

[Serializable]
class Compliant
{
    [WithConditional<int>]
    int Property { get; set; }
}

[Conditional("MAGIC_CONSTANT")]
class WithConditionalAttribute<T> : Attribute { }

Hey Corniel, this sounds like a good idea! I created an internal ticket to add it to our list of rule ideas.

Thanks for the suggestion!

1 Like