Our code reviews still catch MAX_CART_ITEMS in new C# code, usually from developers who came from Java, Python or C.
Quick answer: the C# constant naming convention is PascalCase for every const, whether it’s public, private or local, with no underscore prefix:
public const int MaxCartItems = 50; // not MAX_CART_ITEMS
private const int ReturnWindowDays = 30; // not _returnWindowDays
const int FreeShippingItems = 3; // local constant, same rule
I tested this in a .NET 10 checkout for a Texas outdoor store, then made the build flag your bad names.
What You Need Before You Start with C# Constant Names
- The .NET 10 SDK. Each example is a file-based app you run with
dotnet run File.cs. - VS Code with the C# Dev Kit (see how to create a console application in Visual Studio Code).
- The sample: checkout code for Lone Star Trail Outfitters, a made-up outdoor store in Austin, Texas.
This post covers constants only. For classes, methods, properties and the rest, start with our naming conventions in C# overview.
Step 1: Name const Fields and Local Constants in PascalCase
Microsoft’s C# coding conventions use PascalCase for constant fields and local constants, including private and internal ones. Here’s the store’s checkout with all three:
const int FreeShippingItems = 3; // local constant
int itemsInCart = 2;
Console.WriteLine($"Max cart size: {Checkout.MaxCartItems}");
Console.WriteLine($"Currency: {Checkout.CurrencyCode}");
Console.WriteLine($"Add {FreeShippingItems - itemsInCart} more for free shipping");
static class Checkout
{
public const int MaxCartItems = 50;
public const string CurrencyCode = "USD";
private const int ReturnWindowDays = 30;
public static string ReturnPolicy => $"{ReturnWindowDays}-day returns";
}
Output:
Max cart size: 50
Currency: USD
Add 1 more for free shipping

A shopper with two items is one short of free shipping. A local constant like FreeShippingItems skips the camelCase rule that variables in C# follow, and I like that: you can tell at a glance the value can’t change.
Why Not ALL_CAPS for C# Constants?
SCREAMING_CASE compiles, because the compiler doesn’t enforce naming conventions. It just doesn’t match .NET itself. Ask reflection which built-in fields are real constants:
using System.Reflection;
FieldInfo[] fields =
[
typeof(int).GetField(nameof(int.MaxValue))!,
typeof(TimeSpan).GetField(nameof(TimeSpan.TicksPerDay))!,
typeof(Math).GetField(nameof(Math.PI))!,
typeof(DateTime).GetField(nameof(DateTime.MaxValue))!,
typeof(string).GetField(nameof(string.Empty))!,
];
foreach (FieldInfo f in fields)
Console.WriteLine($"{f.DeclaringType!.Name + "." + f.Name,-20} const: {f.IsLiteral}");
Output:
Int32.MaxValue const: True
TimeSpan.TicksPerDay const: True
Math.PI const: True
DateTime.MaxValue const: False
String.Empty const: False

Three are true const fields, and all five are PascalCase. Math.PI is all caps only because the Framework Design Guidelines capitalize two-letter acronyms, like IOStream.
The same guidelines say not to use underscores in identifiers, so MAX_CART_ITEMS breaks two rules. Our C# variable naming conventions guide lists the casing for everything else.
Step 2: Name a private const Without an Underscore
This is the rule I see broken most. In the .NET runtime style, private fields start with _ and private static fields with s_, but constants don’t, because a constant isn’t a field you can change.
var cart = new CartService("Lone Star Trail Outfitters");
cart.Add(3);
cart.Add(2);
Console.WriteLine(cart.Summary());
class CartService(string storeName)
{
private const int MaxCartItems = 50; // const: PascalCase, no _
private static int s_cartsOpened; // static: s_camelCase
private readonly string _storeName = storeName; // field: _camelCase
private readonly int _cartNumber = ++s_cartsOpened;
private int _itemCount;
public void Add(int quantity) => _itemCount += quantity;
public string Summary() =>
$"{_storeName} cart #{_cartNumber}: {_itemCount}/{MaxCartItems} items";
}
Output:
Lone Star Trail Outfitters cart #1: 5/50 items

The s_ prefix is a runtime team convention, not the Visual Studio default. Our C# fields naming conventions post compares it with plain _camelCase.
Step 3: Use static readonly Instead of const for Values That Change
Microsoft Learn warns against const for prices, version numbers or brand names, because compilers copy a constant’s value into every assembly that uses it. Change it later and those assemblies keep the old value until they’re rebuilt.
Texas’s 6.25% state sales tax rate can change, so our store keeps it in a static readonly field. The name stays PascalCase:
using System.Globalization;
CultureInfo.CurrentCulture = new("en-US");
decimal subtotal = 189.97m;
decimal tax = Math.Round(subtotal * StorePolicy.TexasSalesTaxRate, 2);
Console.WriteLine($"Subtotal {subtotal:C}, state tax {tax:C}");
Console.WriteLine($"Price list: {StorePolicy.PriceListDate:yyyy-MM-dd}");
Console.WriteLine($"Cart limit: {StorePolicy.MaxCartItems} items");
static class StorePolicy
{
public const int MaxCartItems = 50; // fixed for good
public static readonly decimal TexasSalesTaxRate = 0.0625m; // can change
public static readonly DateOnly PriceListDate = new(2026, 11, 1);
}
Output:
Subtotal $189.97, state tax $11.87
Price list: 2026-11-01
Cart limit: 50 items
A $189.97 order gets $11.87 of state tax. static readonly also covers types that can’t be constant. A const must be a number, bool, char, string, enum or null (see data types in C#), so const DateOnly fails with CS0283.
Public static readonly fields use PascalCase, like DateTime.MaxValue; private ones follow your field rule (s_cartTimeout).
Step 4: Group Shared Constants in a Static Class like ApiDefaults
When several files need the same values, we put them in one static class. Same store, now its order API:
Console.WriteLine(ApiDefaults.OrdersRoute);
Console.WriteLine($"Timeout: {ApiDefaults.TimeoutSeconds}s");
Console.WriteLine(Describe(429));
static string Describe(int status) => status switch
{
ApiDefaults.TooManyRequests => $"Rate limited, retry {ApiDefaults.MaxRetries}x",
_ => "OK",
};
static class ApiDefaults
{
public const string BaseRoute = "/api/v1";
public const string OrdersRoute = $"{BaseRoute}/orders";
public const int TimeoutSeconds = 30;
public const int MaxRetries = 3;
public const int TooManyRequests = 429;
}
Output:
/api/v1/orders
Timeout: 30s
Rate limited, retry 3x

OrdersRoute is a constant interpolated string, which works when every part is a constant string. Constants also work as patterns in a switch case in C#, which a static readonly field can’t do.
Name the class by the C# class naming conventions: ApiDefaults, not API_DEFAULTS.
Step 5: Enforce Constant Names with .editorconfig and IDE1006
Code reviews miss things, so we let the build check names. Put this .editorconfig in your project or repo root:
root = true
[*.cs]
# Report naming problems in the build, not only in the editor
dotnet_diagnostic.IDE1006.severity = warning
dotnet_diagnostic.CA1707.severity = warning
dotnet_code_quality.CA1707.api_surface = all
# Constants (fields and locals, any access level): PascalCase
dotnet_naming_symbols.constants.applicable_kinds = field, local
dotnet_naming_symbols.constants.applicable_accessibilities = *
dotnet_naming_symbols.constants.required_modifiers = const
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_rule.constants_are_pascal_case.symbols = constants
dotnet_naming_rule.constants_are_pascal_case.style = pascal_case
dotnet_naming_rule.constants_are_pascal_case.severity = warning
# Private static fields: s_camelCase
dotnet_naming_symbols.private_static_fields.applicable_kinds = field
dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private
dotnet_naming_symbols.private_static_fields.required_modifiers = static
dotnet_naming_style.s_camel_case.capitalization = camel_case
dotnet_naming_style.s_camel_case.required_prefix = s_
dotnet_naming_rule.private_static_fields_are_s_camel.symbols = private_static_fields
dotnet_naming_rule.private_static_fields_are_s_camel.style = s_camel_case
dotnet_naming_rule.private_static_fields_are_s_camel.severity = warning
# Private instance fields: _camelCase
dotnet_naming_symbols.private_fields.applicable_kinds = field
dotnet_naming_symbols.private_fields.applicable_accessibilities = private
dotnet_naming_style.underscore_camel_case.capitalization = camel_case
dotnet_naming_style.underscore_camel_case.required_prefix = _
dotnet_naming_rule.private_fields_are_underscore_camel.symbols = private_fields
dotnet_naming_rule.private_fields_are_underscore_camel.style = underscore_camel_case
dotnet_naming_rule.private_fields_are_underscore_camel.severity = warning
A naming rule’s own severity only shows in the IDE. For dotnet build warnings, set dotnet_diagnostic.IDE1006.severity and turn on EnforceCodeStyleInBuild, which the #:property line does in a .NET 10 file-based app. I packed every mistake into one file:
#:property EnforceCodeStyleInBuild=true
const int maxRetries = 3;
const int MAX_TIMEOUT = 30;
var cart = new CartService();
Console.WriteLine($"Limit: {cart.Limit}, retries: {maxRetries}, timeout: {MAX_TIMEOUT}");
public class CartService
{
public const int MAX_CART_ITEMS = 50;
private const int _maxQuantity = 10;
private const int MaxDiscountPercent = 25;
private static readonly TimeSpan CartTimeout = TimeSpan.FromMinutes(20);
private int itemCount = 0;
public int Limit => MAX_CART_ITEMS - _maxQuantity - MaxDiscountPercent
+ itemCount - CartTimeout.Minutes;
}
dotnet build NamingCheck.cs –no-incremental -v q -nologo:
C:\DotNetDemo\ConstNamingDemo\NamingCheck.cs(10,22): warning CA1707: Remove the underscores from member name CartService.MAX_CART_ITEMS (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1707)
C:\DotNetDemo\ConstNamingDemo\NamingCheck.cs(13,38): warning IDE1006: Naming rule violation: Missing prefix: 's_' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide1006)
C:\DotNetDemo\ConstNamingDemo\NamingCheck.cs(14,17): warning IDE1006: Naming rule violation: Missing prefix: '_' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide1006)
C:\DotNetDemo\ConstNamingDemo\NamingCheck.cs(3,11): warning IDE1006: Naming rule violation: These words must begin with upper case characters: maxRetries (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide1006)
C:\DotNetDemo\ConstNamingDemo\NamingCheck.cs(11,23): warning CA1707: Remove the underscores from member name CartService._maxQuantity (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1707)
C:\DotNetDemo\ConstNamingDemo\NamingCheck.cs(11,23): warning IDE1006: Naming rule violation: Prefix '_' is not expected (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide1006)

Important: pascal_case only checks the first letter, so the local MAX_TIMEOUT passed. CA1707 caught MAX_CART_ITEMS, but it skips locals, so you still need a reviewer for those.
MaxDiscountPercent passed too, so the const rule beat the s_ rule for private constants.
C# Constant Naming Cheat Sheet
| What you’re naming | Convention | Example |
|---|---|---|
public const field | PascalCase | MaxCartItems |
private / internal const | PascalCase, no prefix | ReturnWindowDays |
| Local constant | PascalCase | FreeShippingItems |
public static readonly | PascalCase | TexasSalesTaxRate |
private static readonly | s_camelCase (runtime style) | s_cartTimeout |
| Class of constants | PascalCase noun | ApiDefaults |
| Two-letter acronym | Both letters upper | Math.PI, IOTimeout |
Team Rules for Naming Constants in C#
These go straight into our coding standard, and you can copy them into yours:
- PascalCase for every
const, with no_,korc_prefix. - Name the meaning, not the value:
MaxCartItems, neverFifty. Boolean constants read like boolean variable names:IsTaxExempt. constonly for values that never change;static readonlyfor rates, dates, prices and versions.- One static class per area (
ApiDefaults,StorePolicy), and the.editorconfigabove in the repo root.
Common Mistakes to Avoid with C# Constant Names
| Mistake | What happens | Fix |
|---|---|---|
MAX_CART_ITEMS | CA1707 warning, looks foreign next to .NET APIs | MaxCartItems |
private const int _maxQuantity | IDE1006: prefix ‘_’ is not expected | MaxQuantity |
const int maxRetries (local) | IDE1006: must begin with upper case | MaxRetries |
A tax rate as public const | Other assemblies keep the old value | static readonly |
const DateOnly | CS0283, the type can’t be const | static readonly DateOnly |
Next Steps
Enum members follow the same PascalCase rule, with a few extra rules for singular and flags names. Our C# enum naming conventions guide is the natural next read.
We’d pair these with this post too:
- C# method naming conventions with Async and verb rules
- Constructors in C#, where readonly fields get their values
- Enum in C# when a constant should be a set of choices
- What’s new in C# 14
Frequently Asked Questions
Should C# constants be uppercase?
No. Use PascalCase, like MaxCartItems. ALL_CAPS compiles, but it doesn’t match .NET’s own constants such as int.MaxValue, and CA1707 flags the underscores.
How do you name a private const in C#?
PascalCase with no prefix: private const int MaxQuantity = 10;. The _ and s_ prefixes are only for non-constant fields.
Are local constants PascalCase in C#?
Yes, even though ordinary local variables are camelCase.
What’s the naming convention for static readonly fields?
Public ones are PascalCase, like DateTime.MaxValue. Private ones follow your field rule, s_camelCase in the .NET runtime style.
How do I enforce constant naming in a C# project?
Add naming rules to .editorconfig, set IDE1006 to warning and turn on EnforceCodeStyleInBuild. The syntax is in Code-style naming rules on Microsoft Learn.
Bijay Kumar is a renowned software engineer, accomplished author, and distinguished Microsoft Most Valuable Professional (MVP) specializing in SharePoint. With a rich professional background spanning over 15 years, Bijay has established himself as an authority in the field of information technology. He possesses unparalleled expertise in multiple programming languages and technologies such as ASP.NET, ASP.NET MVC, C#.NET, and SharePoint, which has enabled him to develop innovative and cutting-edge solutions for clients across the globe. Read more…