Generic Attributes

C# 11, the latest version of Microsoft’s programming language, has arrived, bringing with it a host of new features and improvements. And among these new features, there’s one that I think deserves special attention: Generic Attributes.

Traditional Attributes

If you’re not familiar with attributes in C#, they’re basically metadata that you can attach to your code to provide additional information to the compiler. For example, you might use the [Obsolete] attribute to indicate that a particular method or class should no longer be used.

The problem with traditional attributes, however, is that they’re not very flexible. You can’t pass in any parameters to them, and you can only apply them to classes, methods, and other members of your code.

The power of Generics

Well, with C# 11, that’s all changed. With the introduction of Generic Attributes, you can now pass in parameters to your attributes, making them much more flexible and powerful.

Let’s look at a simple example. Let’s say you want to write an attribute that you can use to specify a default value for a property. With traditional attributes, you’d have to write a separate attribute for each type of property. But with C# 11’s Generic Attributes, you can write a single attribute that works for any type of property.

Here’s what the attribute might look like:

[AttributeUsage(AttributeTargets.Property)]
public class DefaultValueAttribute<T> : Attribute
{
    public T Value { get; }

    public DefaultValueAttribute(T value)
    {
        Value = value;
    }
}

And here’s how you’d use the attribute:

public class MyClass
{
    [DefaultValue<int>(0)]
    public int? MyIntProperty { get; set; }

    [DefaultValue<string>("Hello, world!")]
    public string? MyStringProperty { get; set; }
}

As you can see, the DefaultValueAttribute is generic, which means that you can use it with any type of property. And because it takes a parameter, you can specify the default value for each property. You would need to enforce the default value attribute elsewhere.

Conclusion

But the benefits of Generic Attributes don’t stop there. You can use them with any other part of your code, like classes, methods, and events. You can even use them with other attributes!

And with the power of C# 11’s type inference, you can write code that’s shorter, clearer, and easier to read.

So there you have it: the power of Generic Attributes in C# 11. It’s a simple yet powerful feature. So go ahead and give it a try!