C# Naming Conventions
Introduction
Naming conventions are a set of rules for choosing the character sequences to be used for identifiers which denote variables, types, functions, and other entities in source code and documentation. Following consistent naming conventions makes your code more readable and easier to maintain.
In this guide, you'll learn the standard C# naming conventions used by professional developers and recommended by Microsoft. By adopting these conventions, your code will be more intuitive to read, easier to maintain, and consistent with the broader C# ecosystem.
Why Naming Conventions Matter
Before diving into specific rules, let's understand why naming conventions are important:
- Readability: Well-named entities immediately convey their purpose
- Maintainability: Consistent naming makes future code changes easier
- Collaboration: Team members can understand each other's code more quickly
- Industry Standards: Following conventions helps you adapt to professional environments
Basic C# Naming Conventions
PascalCase
Use PascalCase for:
- Class names
- Interface names
- Method names
- Property names
- Namespace names
- Enum types and values
PascalCase means the first letter of each word is capitalized, including the first word.
// Good Examples
public class CustomerOrder
{
public decimal TotalAmount { get; set; }
public void ProcessPayment()
{
// Method implementation
}
}
public enum OrderStatus
{
Pending,
Processing,
Completed,
Cancelled
}
camelCase
Use camelCase for:
- Local variables
- Method parameters
- Private fields
camelCase means the first letter of each word is capitalized except for the first word.
public class Order
{
// Private field (camelCase with underscore prefix)
private int _orderNumber;
// Method with camelCase parameters
public void CreateOrder(string customerName, decimal orderAmount)
{
// Local variables in camelCase
int itemCount = 0;
bool isValid = ValidateOrder();
// Method implementation
}
}
Naming Conventions for Different Types
Classes and Structs
- Use nouns or noun phrases
- Use PascalCase
- Don't use prefixes
// Good
public class Customer { }
public class OrderItem { }
public struct Point { }
// Avoid
public class clsCustomer { } // Don't use 'cls' prefix
public class CCustomer { } // Don't use 'C' prefix
Interfaces
- Use PascalCase
- Start with the letter 'I'
- Use nouns, noun phrases, or adjectives
// Good
public interface IDisposable { }
public interface IFormattable { }
public interface IComparable { }
// Avoid
public interface Disposable { } // Missing 'I' prefix
public interface IGetCustomerData { } // Verb phrase instead of noun/adjective
Methods
- Use verb or verb phrases
- Use PascalCase
// Good
public void SaveChanges() { }
public bool ValidateInput() { }
public Customer GetCustomerById(int id) { }
// Avoid
public void Data() { } // Not a verb
public bool InputValidation() { } // Not a clear verb phrase
Properties
- Use nouns, noun phrases, or adjectives
- Use PascalCase
- Consider using same name as the type for properties returning the type
// Good
public string Name { get; set; }
public decimal Price { get; set; }
public DateTime CreatedDate { get; set; }
public Customer Customer { get; set; } // Property named same as its type
// Avoid
public string GetName { get; set; } // Don't use verbs
public decimal the_price { get; set; } // Wrong casing
Fields
Private and Internal Fields
- Use camelCase
- Consider prefixing with underscore (_)
public class Customer
{
// Private fields with underscore prefix (common practice)
private string _firstName;
private DateTime _registrationDate;
// Internal field
internal int customerCode;
}
Public Fields
Avoid public fields whenever possible. Use properties instead. If you must use public fields (e.g., for constants):
- Use PascalCase
- Use ALL_CAPS for very commonly known abbreviations
public class Constants
{
// Constants use PascalCase
public const string DefaultConnectionString = "...";
public const int MaxRetryCount = 5;
// Well-known abbreviations can be all uppercase
public const string HTML = "...";
public const string HTTP = "...";
}
Parameters and Local Variables
- Use camelCase
- Use descriptive names
- Avoid single-letter names except for simple loop counters
// Parameters using camelCase
public void RegisterUser(string userName, string emailAddress, int userAge)
{
// Local variables using camelCase
bool isValid = true;
DateTime registrationDate = DateTime.Now;
// Exception: simple loop counters can use single letters
for (int i = 0; i < 10; i++)
{
// Loop body
}
}
Abbreviations and Acronyms
- For acronyms of two characters, use both uppercase (e.g.,
IO
,DB
) - For acronyms of three or more characters, only capitalize the first letter (e.g.,
Http
,Xml
,Json
)
// Good
public class HttpClient { }
public class XmlDocument { }
public class IoDevice { }
// Avoid
public class HTTPClient { } // Should be HttpClient
public class XMLDocument { } // Should be XmlDocument
Namespaces
- Use PascalCase
- Use company name followed by technology and/or feature area
- Separate namespace components with periods
- Don't use the same name for a namespace and a type
// Good
namespace Microsoft.Office.PowerPoint { }
namespace MyCompany.Security.Cryptography { }
// Avoid
namespace mycompany.security { } // Incorrect casing
namespace Utilities { } // Too generic, missing company name
Real-World Example
Let's put it all together in a practical example:
using System;
using System.Collections.Generic;
namespace MyCompany.OnlineStore.OrderProcessing
{
public interface IOrderProcessor
{
bool ProcessOrder(Order order);
OrderStatus CheckOrderStatus(int orderId);
}
public class Order
{
private readonly List<OrderItem> _items;
private readonly DateTime _orderDate;
private OrderStatus _status;
public int OrderId { get; private set; }
public Customer Customer { get; set; }
public decimal TotalAmount { get; private set; }
public IReadOnlyList<OrderItem> Items => _items;
public OrderStatus Status => _status;
public Order(int orderId, Customer customer)
{
OrderId = orderId;
Customer = customer;
_items = new List<OrderItem>();
_orderDate = DateTime.Now;
_status = OrderStatus.New;
}
public void AddItem(OrderItem item)
{
_items.Add(item);
RecalculateTotalAmount();
}
private void RecalculateTotalAmount()
{
decimal total = 0;
foreach (var item in _items)
{
total += item.Price * item.Quantity;
}
TotalAmount = total;
}
public bool UpdateStatus(OrderStatus newStatus)
{
// Business logic to validate status transition
bool isValidTransition = ValidateStatusTransition(_status, newStatus);
if (isValidTransition)
{
_status = newStatus;
return true;
}
return false;
}
private bool ValidateStatusTransition(OrderStatus currentStatus, OrderStatus newStatus)
{
// Implementation
return true;
}
}
public class OrderItem
{
public string ProductName { get; set; }
public decimal Price { get; set; }
public int Quantity { get; set; }
}
public enum OrderStatus
{
New,
Processing,
Shipped,
Delivered,
Cancelled
}
}
Special Cases and Exceptions
Private Fields Prefixing
While the leading underscore is common practice for private fields, some teams opt for alternatives:
public class Customer
{
// Option 1: Underscore prefix (most common)
private string _name;
// Option 2: No prefix (also acceptable)
private string name;
// Option 3: 'm_' prefix (older style, less common now)
private string m_name;
}
Hungarian Notation
C# does not use Hungarian notation (prefixing variable names with their type information):
// Bad (Hungarian notation)
string strName;
int iCount;
bool bIsActive;
// Good
string name;
int count;
bool isActive;
Common Mistakes to Avoid
-
Inconsistent casing
csharp// Inconsistent - Don't do this
public class customer { } // Should be Customer
public void Save_data() { } // Should be SaveData -
Unclear abbreviations
csharp// Unclear - Don't do this
public int CalcTDR() { } // What is TDR?
// Better
public int CalculateTotalDiscountRate() { } -
Non-descriptive names
csharp// Non-descriptive - Don't do this
public void Process() { }
public string Get() { }
// Better
public void ProcessPayment() { }
public string GetCustomerName() { }
Summary
Following C# naming conventions makes your code more readable, maintainable, and consistent with industry standards. Here's a quick reference:
- PascalCase: Classes, interfaces, methods, properties, namespaces, public fields, enums
- camelCase: Local variables, method parameters, private fields
- Prefix interfaces with 'I'
- Consider prefixing private fields with underscore (_)
- Use descriptive names that reveal intent
- Avoid Hungarian notation and unnecessary abbreviations
By following these conventions, you'll write C# code that's easier to understand and maintain, and you'll fit in better with the broader C# development community.
Additional Resources
Exercises
-
Refactor the following code to follow proper C# naming conventions:
csharppublic class customer_data
{
private string First_name;
public int AGE;
public void save_customer() { }
public bool VALIDATE() { }
} -
Create a small class hierarchy representing a blog system (Blog, Post, Comment, Author) following all the naming conventions covered in this guide.
-
Review an existing project you've worked on and identify naming convention violations. Make a list of the changes needed to make it consistent with standard C# conventions.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)