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 at Converge 360.

comments powered by Disqus

Featured

  • Mastering Blazor Authentication and Authorization

    At the Visual Studio Live! @ Microsoft HQ developer conference set for August, Rockford Lhotka will explain the ins and outs of authentication across Blazor Server, WebAssembly, and .NET MAUI Hybrid apps, and show how to use identity and claims to customize application behavior through fine-grained authorization.

  • Linear Support Vector Regression from Scratch Using C# with Evolutionary Training

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the linear support vector regression (linear SVR) technique, where the goal is to predict a single numeric value. A linear SVR model uses an unusual error/loss function and cannot be trained using standard simple techniques, and so evolutionary optimization training is used.

  • Low-Code Report Says AI Will Enhance, Not Replace DIY Dev Tools

    Along with replacing software developers and possibly killing humanity, advanced AI is seen by many as a death knell for the do-it-yourself, low-code/no-code tooling industry, but a new report belies that notion.

  • Vibe Coding with Latest Visual Studio Preview

    Microsoft's latest Visual Studio preview facilitates "vibe coding," where developers mainly use GitHub Copilot AI to do all the programming in accordance with spoken or typed instructions.

  • Steve Sanderson Previews AI App Dev: Small Models, Agents and a Blazor Voice Assistant

    Blazor creator Steve Sanderson presented a keynote at the recent NDC London 2025 conference where he previewed the future of .NET application development with smaller AI models and autonomous agents, along with showcasing a new Blazor voice assistant project demonstrating cutting-edge functionality.

Subscribe on YouTube