Generic Attributes and More — Visual Studio Magazine
News
C# 11 Features Preview in Visual Studio: Generic Attributes and More
A new “What’s New in C# 11” post explains the new features available in preview with the latest tools: NET 6.0.200 SDK or Visual Studio 2022 v17.1.
First, support for generic attributes or the ability to create a generic class based on System.Attribute
. The Attribute class provides a way to associate information with code declaratively, so that a ObsoleteAttribute
indicates code that has been deprecated and should no longer be used, signaling the compiler to look for instances of the attribute and do something corrective in response.
A Microsoft C# 10 documentation for generic attributes (support has been deferred to C# 11) explains the motivation: “Currently, attribute authors can take a System.Type
as a parameter and ask users to pass a typeof
expression to provide the attribute with the types it needs. However, outside of parsers, there is no way for an attribute author to restrict the types allowed to be passed to an attribute via typeof
. If attributes could be generic, then attribute authors could use the existing system of type parameter constraints to express requirements for the types they take as input.”
As the graphic below shows, support for generic attributes is just one of many new features planned for C#:
Support for wildcard attributes was C# expert Jason Bock’s answer to the question, “What C# feature do you wish Microsoft had delivered, but just didn’t come to fruition?” in the September 2021 article “Q&A with Jason Bock: What’s New in C# 10.”
“Generic attributes,” Bock replied. “It’s a capability the CLR has had for a long time, but it’s never been demonstrated in C#. You can define generic attributes in .NET’s intermediate language — IL — and consume them in C#, but you can’t define them directly in C# There are cases where I think this feature would be useful, and I hope it does in C# at some point.
His wishes came true in Visual Studio 17.1, where a developer only has to set
click “preview” to enable preview features. Of these, “Allow Wildcard Attributes” has been a long time coming, having been in the works for at least five years.
The new “What’s New in C# 11” documentation just released on March 11 provides more details on its impending manifestation.
“You can declare a generic class whose base class is System.Attribute. This provides a more convenient syntax for attributes that require a System.Type parameter. Previously, you had to create an attribute that takes a Type
as a constructor parameter:”
// Before C# 11: public class TypeAttribute : Attribute { public TypeAttribute(Type t) => ParamType = t; public Type ParamType { get; } }
After using the tyepof
operator to apply the attribute, a developer can create a generic attribute and specify the type parameter to use the new functionality. However, some code constructs are not allowed because when a generic attribute is used, it must be completely closed. In other words, it cannot contain any type parameters. Here are some examples :
-
Example 1:
public class GenericType
{ [GenericAttribute ()] // Not allowed! generic attributes must be fully constructed types. public string Method() => default; } -
Example 2:
using System; using System.Collections.Generic; public class Attr
: Attribute { } public class Program { [Attr ] // error [Attr - ] // error
void M() { }
}
>
In addition to explaining the motivation behind the approach, Microsoft also lists a downside of the scheme: “Removing the restriction, analyzing the implications, and adding the appropriate tests is work.”
An alternative is also listed: “Attribute authors who want users to be able to discover the requirements of the types they supply to attributes should write parsers and guide their users to use those parsers in their releases.”
An unresolved question about the diet reads:
- [x] What does mean
AllowMultiple = false
mean on a generic attribute? If we have[Attr
and] [Attr
both used on one symbol, does that mean “more than one” of the attribute is used?
- For now, we’re inclined to take the more restrictive route here and consider the original attribute class definition to decide if more than one of them has been applied. In other words,
[Attr
and] [Attr
applied together are incompatible withAllowMultiple = false
.
The March 11 announcement also notes that type arguments must satisfy the same restrictions as typeof
and it lists some disallowed metadata annotations.
The post also details static abstract members in interfaces, a runtime preview feature also available with this setting:
.
“You can add static abstract members in interfaces to define interfaces that include overloadable operators, other static members, and static properties,” Microsoft said. “The main scenario of this feature is to use mathematical operators in generic types. More information on this is available in the tutorial titled “Exploring Static Abstract Interface Members.”
While developer attitudes towards generic attributes seem to be mostly positive, judging by GitHub feedback, other C# 11 preview features that Microsoft has discussed have drawn a lot of developer ire, particularly the check for zero parameters. Read more about this in the article “Devs Sound Off on C# 11 Preview Features Like Parameter Null Checking”.
About the Author
David Ramel is an editor and writer for Converge360.
Comments are closed.