.NET Naming Standards
Introduction
Consistent naming standards are a fundamental aspect of writing clean, maintainable code in any programming language. In the .NET ecosystem, following established naming conventions makes your code more readable, predictable, and professional. These standards help developers quickly understand code written by others and promote consistency across the larger .NET community.
This guide will introduce you to the official Microsoft .NET naming conventions and provide practical examples to help you apply them in your own projects. Whether you're writing in C#, VB.NET, or F#, these principles will improve your code quality and make collaboration easier.
Why Naming Standards Matter
Before diving into the specific conventions, let's understand why naming standards are important:
- Readability: Well-named identifiers make code self-documenting
- Maintainability: Consistent naming makes code easier to update and debug
- Collaboration: Standardized conventions help team members understand each other's code
- Integration: Following community standards makes it easier to use libraries and frameworks
Basic Principles of .NET Naming
The .NET naming conventions follow several core principles:
- Use meaningful, descriptive names that clearly convey purpose
- Avoid abbreviations unless they're universally recognized
- Be consistent with capitalization patterns
- Don't use Hungarian notation (prefixing variable names with type information)
- Choose clarity over brevity (but avoid unnecessarily long names)
Capitalization Conventions
.NET uses two primary capitalization styles:
Pascal Case (PascalCase)
- First letter of each word is capitalized
- Used for: class names, method names, namespaces, properties, public fields
- Examples:
CustomerService
,CalculateTotalPrice
,FileStream
Camel Case (camelCase)
- First letter is lowercase, first letter of each subsequent word is capitalized
- Used for: parameters, local variables, private fields
- Examples:
firstName
,totalAmount
,isCustomerActive
Naming Different Types of Identifiers
Namespaces
Use Pascal case with a hierarchical structure:
// Good
namespace Company.Product.Feature
// Not recommended
namespace company.product
Namespaces should typically follow a structure like Company.Technology.Feature
.
Classes and Structs
Use nouns or noun phrases in Pascal case:
// Good
public class Customer
{
}
public class OrderProcessor
{
}
// Not recommended
public class DoProcessing
{
}
Interfaces
Use Pascal case with an "I" prefix followed by a noun or adjective:
// Good
public interface IDisposable
{
}
public interface IAccessible
{
}
// Not recommended
public interface Disposable
{
}
Methods
Use verbs or verb phrases in Pascal case:
// Good
public void CalculateTax()
{
}
public string GetFullName()
{
}
// Not recommended
public void Tax()
{
}
Properties
Use nouns, noun phrases, or adjectives in Pascal case:
// Good
public string FirstName { get; set; }
public bool IsActive { get; set; }
public List<Order> Orders { get; private set; }
// Not recommended
public string getname { get; set; }
Fields
- For public fields (rare), use Pascal case
- For private or internal fields, use camel case with an underscore prefix
// Private fields
private string _firstName;
private readonly DateTime _startDate;
// Public fields (prefer properties when possible)
public string ConnectionString;
Parameters and Local Variables
Use camel case:
public void ProcessOrder(int orderId, decimal totalAmount)
{
bool isValid = Validate(orderId);
string orderNumber = GenerateNumber();
// Rest of the method...
}
Constants and Static Readonly Fields
Use Pascal case:
public const int MaximumAttempts = 5;
public static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(30);
// Not recommended
public const int MAX_ATTEMPTS = 5;
Enumerations
Use Pascal case for the enum type and its values:
public enum PaymentMethod
{
Cash,
CreditCard,
DebitCard,
ElectronicTransfer
}
// Not recommended
public enum paymentMethod
{
cash,
CREDIT_CARD
}
Special Naming Patterns
Acronyms
When using acronyms, treat acronyms with 2 letters as a single word and capitalize only the first letter of acronyms with 3 or more letters:
// Good
public class DbConnection // Two-letter acronym
public class HttpRequest // Three-letter acronym
public string Url { get; set; } // Three-letter acronym as property
// Not recommended
public class DBConnection
public class HTTPRequest
Async Methods
Append "Async" suffix to methods that return Task
or Task<T>
:
// Good
public async Task<Customer> GetCustomerAsync()
{
// Implementation...
}
// Not recommended
public async Task<Customer> GetCustomer()
{
// Implementation...
}
Event Handlers
Use "EventName" + "EventHandler" naming pattern for event handler delegates:
// Good
public delegate void ButtonClickEventHandler(object sender, EventArgs e);
// Not recommended
public delegate void ButtonClicked(object sender, EventArgs e);
Generic Type Parameters
Use descriptive names with "T" prefix or single letters for simple cases:
// Good - descriptive generic type
public interface IRepository<TEntity>
{
// Implementation...
}
// Good - simple generic type
public class Pair<T, U>
{
// Implementation...
}
Practical Example: Building a Customer Management System
Let's apply these naming conventions in a real-world example of a simple customer management system:
namespace CompanyName.CustomerManagement
{
public interface ICustomerRepository
{
Task<Customer> GetCustomerByIdAsync(int customerId);
Task<IEnumerable<Customer>> GetActiveCustomersAsync();
Task<bool> AddCustomerAsync(Customer customer);
}
public class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime RegistrationDate { get; set; }
public CustomerStatus Status { get; set; }
public bool IsActive => Status == CustomerStatus.Active;
public string GetFullName()
{
return $"{FirstName} {LastName}";
}
}
public enum CustomerStatus
{
Inactive,
Active,
Suspended,
Closed
}
public class SqlCustomerRepository : ICustomerRepository
{
private readonly string _connectionString;
private const int CommandTimeout = 30;
public SqlCustomerRepository(string connectionString)
{
_connectionString = connectionString;
}
public async Task<Customer> GetCustomerByIdAsync(int customerId)
{
// Implementation...
return new Customer();
}
public async Task<IEnumerable<Customer>> GetActiveCustomersAsync()
{
// Implementation...
return new List<Customer>();
}
public async Task<bool> AddCustomerAsync(Customer customer)
{
if (customer == null)
{
throw new ArgumentNullException(nameof(customer));
}
bool isSuccess = false;
try
{
// Database operations...
isSuccess = true;
}
catch (Exception ex)
{
// Error handling...
}
return isSuccess;
}
}
}
Notice how following the naming conventions makes the code self-explanatory. Even without comments, you can understand what each component does and how they relate to each other.
Common Naming Mistakes to Avoid
-
Hungarian notation: Don't prefix variables with type indicators
csharp// Avoid
string strName;
// Preferred
string name; -
Unclear abbreviations: Avoid abbreviations that aren't universally recognized
csharp// Avoid
var calc = new PriceCalc();
// Preferred
var calculator = new PriceCalculator(); -
Meaningless names: Avoid names that don't convey purpose
csharp// Avoid
public void Process1()
// Preferred
public void ProcessPayment() -
Inconsistent casing: Be consistent with your capitalization
csharp// Avoid mixing cases
private string firstName;
private string LastName;
// Preferred
private string firstName;
private string lastName;
Summary
Following .NET naming conventions leads to more readable, maintainable, and professional code. The key principles include:
- Use PascalCase for types, members, namespaces, and public fields
- Use camelCase for parameters and local variables
- Use meaningful, descriptive names
- Prefix interfaces with "I"
- Suffix async methods with "Async"
- Follow established patterns for special cases like generics and event handlers
By consistently applying these standards, you'll write code that's easier to understand, maintain, and collaborate on—skills that will serve you well throughout your .NET development career.
Additional Resources
Exercises
-
Refactor the following code to follow .NET naming conventions:
csharppublic class data_processor
{
private int MAX_SIZE = 100;
public bool process_data(string Data)
{
var isOK = validate(Data);
return isOK;
}
private bool validate(string d)
{
return d.Length <= MAX_SIZE;
}
} -
Create a simple order processing system with at least one interface, two classes, and an enum, following all the naming conventions covered in this guide.
-
Review an existing codebase (either your own or an open-source project) and identify naming convention violations. Create a list of improvements that could be made.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)