Recently I had the opportunity to attend a conference talk by Scott Kay at TechBash. Scott’s talk covered all the new features released in C# 11 earlier this week. Most of the new features were incremental language improvements such as the new required keyword.
However, one of these features stuck me immediately as something we don’t need — and also really need to do more.
In this article we’ll cover the CS8981 compiler warning that was introduced in C# 11.
The CS8981 Compiler Warning
You get the CS8981 compiler warning when you declare a Type consisting of only lowercase letters. The compiler warning is accompanied by the following text:
The type name [your type name] only contains lower-cased ascii characters. Such names may become for the language.
The following C# code would generate the CS8981 compiler warning:
public class test
{
public string Text {get; set;}
}
This code still compiles, but you see a warning indicator in Visual Studio 2022:
That’s it. That’s the new feature.
Let’s talk about why this exists and why I like it so much.
Why do we need the CS8981 Compiler Warning?
If you’re anything like me, you declare your class names in C# as PascalCased. Class names like CustomerService
and RequiredValidator
are standard in dotnet and follow the dotnet naming guidelines.
People like me (and most devs I’ve worked with) will never bump into the CS8981 compiler warning at all.
So why do we need it?
Adding the CS8981 compiler warning to the C# language gives us a few important things:
- It helps new developers discover language naming guidelines in an intuitive but not disruptive way
- It encourages developers to avoid names that may cause conflicts with future C# language features
- Flagging these things now allows the C# language to grow and expand in safe and guided ways by introducing new reserved words without impacting existing Type declarations
Of these arguments, I find the nudges for new developers to be the most compelling.
How CS8981 Helps new C# Developers
Many industry experts forget how intimidating entering a broad language with over 20 years of syntax and library changes can be. This is particularly true for people like most of my students who learn C# as their first programming languages.
While I understand the motivation of the CS8981 compiler warning is to make introducing future language improvements easier, I think there’s significant value of flagging good behavior for new developers.
As the C# language continues to expand, we have accumulated a growing number of ways of declaring methods, properties, Types, variables, and more.
New developers must learn what all of these pieces of syntax mean as they encounter them in code, and they must also learn when to use one versus another.
Now, put yourself in the mind of a new developer. You’re trying to solve a problem. You try all the syntax you remember to express your intent. However, new learners will invariably accidentally declare nested classes or methods without meaning to do so. They will accidentally shadow variables by reusing the same names. They will violate language standards and guidelines and find other ways of shooting themselves in the foot.
Reference materials and mentoring can help with all of these things, but new learners are still going to bump into these issues while learning on their own (which is an important phase for solidifying those skills).
Language features like the CS8981 compiler warning can really help new learners discover best practices.
While you or I may not need CS8981 right now, the next generation of developers will benefit greatly from it and things like it.
I’m excited to see more changes like the CS8981 compiler warning to direct new devs towards safe practices. I’d love to see a more opinionated dotnet that guides early users towards safe and consistent practices, then helps them grow over time to more advanced features.
Top comments (1)
What is the category for CS9891? I'm trying to suppress it for my migrations folder as I don't want to go through and rename the patches.
[assembly: SuppressMessage("Code Quality", "CS8981", Justification = "", Scope = "namespaceanddescendants", Target = "~N:MyNamespace.Domain.Migrations")]