News

C# 11 Features Now Previewing in Visual Studio: Generic Attributes and More

A new "What's new in C# 11" post explains new features available in preview with the latest tooling bits: NET 6.0.200 SDK or Visual Studio 2022 v17.1.

First on tap is generic attributes support, or the ability to create a generic class based on System.Attribute. The Attribute class provides a way of associating information with code in a declarative way, such that an ObsoleteAttribute indicates code that is obsolete and shouldn't be used anymore, signaling the compiler to look for instances of the attribute and do something corrective in response.

Some C# 10 Microsoft documentation for generic attributes (support was postponed to C# 11) explains the motivation: "Currently attribute authors can take a System.Type as a parameter and have users pass a typeof expression to provide the attribute with types that it needs. However, outside of analyzers, there's no way for an attribute author to constrain what types are 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 the requirements for the types they take as input."

As the graphic below shows, support for generic attributes is but one of many new features planned for C#:

C# Plans
[Click on image for larger view.] C# Plans (source: Microsoft).

Generic attribute support was the answer C# expert Jason Bock provided when asked "What's a C# feature that you wish Microsoft would come out with, but it just hasn't materialized?" in the September 2021 article "Q&A with Jason Bock: What's New in C# 10."

"Generic attributes," Bock replied. "This is a capability that the CLR has had for a long time, but it's never been surfaced in C#. You can define generic attributes in the intermediate language of .NET -- IL -- and consume them in C#, but you can't define them in C# directly. There are cases where I think this feature would be useful, and I'm hoping it makes it into C# at some point."

His wishes have come true in Visual Studio 17.1, where a developer need only set <LangVersion> to "preview" to enable preview features. Among those, "Allow Generic Attributes" has been a long time coming, in the works for at least five years.

New "What's new in C# 11" documentation just published 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'd need to create an attribute that takes a Type as its 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 feature. However, certain code constructs aren't allowed because when a generic attribute is used, it needs to be fully closed. In other words, it can't contain any type parameters. Here are a couple examples:

  • Example 1:
    public class GenericType<T>
        {
          [GenericAttribute<T>()] // Not allowed! generic attributes must be fully constructed types.
          public string Method() => default;
        }
  • Example 2:
    using System;
        using System.Collections.Generic;
        
        public class Attr<T1> : Attribute { }
        
        public class Program<T2>
        {
          [Attr<T2>] // error
          [Attr] // error
          void M() { }
        }

In addition to explaining the motivation behind the approach, Microsoft also lists a drawback of the scheme: "Removing the restriction, reasoning out 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 for the types they provide to attributes need to write analyzers and guide their users to use those analyzers in their builds."

An unresolved question about the scheme reads:

  • [x] What does AllowMultiple = false mean on a generic attribute? If we have [Attr<string>] and [Attr<object>] both used on a symbol, does that mean "multiple" of the attribute are in use?
  • For now we are inclined to take the more restrictive route here and consider the attribute class's original definition when deciding whether multiple of it have been applied. In other words, [Attr<string>] and [Attr<object>] applied together is incompatible with AllowMultiple = false.

The March 11 announcement also notes that type arguments must satisfy the same restrictions as the typeof operator, and it lists some disallowed metadata annotations.

The post also details static abstract members in interfaces, a runtime preview feature that is also available by this setting: <EnablePreviewFeatures>True</EnablePreviewFeatures>.

"You can add static abstract members in interfaces to define interfaces that include overloadable operators, other static members, and static properties," Microsoft said. "The primary scenario for this feature is to use mathematical operators in generic types." More on that is available in the tutorial titled "Explore static abstract interface members."

While developer attitudes toward generic attributes seem to be mostly positive, judging by GitHub comments, other C# 11 preview features that Microsoft has discussed drew much developer ire, especially parameter null checking. Read more about that 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 powered by Disqus

Featured

  • AI for GitHub Collaboration? Maybe Not So Much

    No doubt GitHub Copilot has been a boon for developers, but AI might not be the best tool for collaboration, according to developers weighing in on a recent social media post from the GitHub team.

  • Visual Studio 2022 Getting VS Code 'Command Palette' Equivalent

    As any Visual Studio Code user knows, the editor's command palette is a powerful tool for getting things done quickly, without having to navigate through menus and dialogs. Now, we learn how an equivalent is coming for Microsoft's flagship Visual Studio IDE, invoked by the same familiar Ctrl+Shift+P keyboard shortcut.

  • .NET 9 Preview 3: 'I've Been Waiting 9 Years for This API!'

    Microsoft's third preview of .NET 9 sees a lot of minor tweaks and fixes with no earth-shaking new functionality, but little things can be important to individual developers.

  • Data Anomaly Detection Using a Neural Autoencoder with C#

    Dr. James McCaffrey of Microsoft Research tackles the process of examining a set of source data to find data items that are different in some way from the majority of the source items.

  • What's New for Python, Java in Visual Studio Code

    Microsoft announced March 2024 updates to its Python and Java extensions for Visual Studio Code, the open source-based, cross-platform code editor that has repeatedly been named the No. 1 tool in major development surveys.

Subscribe on YouTube