C# Code Style
Writing clean, consistent code isn't just about making your programs work—it's also about making them understandable and maintainable. In this guide, you'll learn the standard C# code style conventions that will help you write more professional and readable code.
Why Code Style Matters
Before diving into specific conventions, let's understand why code style is important:
- Readability: Consistent code is easier to read and understand
- Maintainability: Makes future updates simpler for you and other developers
- Professionalism: Shows attention to detail and care for your craft
- Team Harmony: Reduces conflicts in collaborative environments
Naming Conventions
Pascal Case
Use Pascal Case (first letter of each word capitalized) for:
- Classes and Types
- Methods
- Properties
- Namespaces
// Good
public class PlayerController
{
public void UpdatePosition() { }
public int HealthPoints { get; set; }
}
// Avoid
public class playercontroller
{
public void updateposition() { }
public int healthpoints { get; set; }
}
Camel Case
Use Camel Case (first letter lowercase, rest of words capitalized) for:
- Local variables
- Method parameters
public void CalculateTotal(int itemCount, double unitPrice)
{
// Local variables use camelCase
int totalItems = itemCount;
double orderValue = totalItems * unitPrice;
Console.WriteLine($"Order value: ${orderValue}");
}
Underscores for Private Fields
Use a leading underscore for private fields:
public class Customer
{
private string _firstName;
private string _lastName;
public string FullName => $"{_firstName} {_lastName}";
}
Bracing and Indentation
Bracing Style
C# traditionally uses the Allman style (opening braces on a new line):
// Recommended Allman style
public void ProcessData()
{
foreach (var item in items)
{
if (item.IsValid)
{
item.Process();
}
}
}
// Alternative K&R style (common in some teams)
public void ProcessData() {
foreach (var item in items) {
if (item.IsValid) {
item.Process();
}
}
}
Indentation
Use 4 spaces for indentation (not tabs) to ensure consistent formatting across different editors:
public class Example
{
public void Method()
{
// 4 spaces for indentation
if (condition)
{
// 4 more spaces
DoSomething();
}
}
}
Code Organization
File Organization
Structure your code files logically:
- Namespace declarations
- Using directives
- Classes, structs, or interfaces
- Within a class:
- Fields
- Properties
- Constructors
- Methods
using System;
using System.Collections.Generic;
namespace MyApplication.Core
{
public class UserProfile
{
// Fields
private readonly string _userId;
private readonly DateTime _createdDate;
// Properties
public string Username { get; set; }
public bool IsActive { get; set; }
// Constructor
public UserProfile(string userId)
{
_userId = userId;
_createdDate = DateTime.Now;
}
// Methods
public void Activate()
{
IsActive = true;
}
public void Deactivate()
{
IsActive = false;
}
}
}
Commenting Practices
XML Documentation Comments
Use XML documentation comments for public members:
/// <summary>
/// Calculates the total price including applicable taxes.
/// </summary>
/// <param name="price">The base price of the product</param>
/// <param name="taxRate">The tax rate as a decimal (e.g., 0.08 for 8%)</param>
/// <returns>The total price with tax applied</returns>
public decimal CalculateTotalWithTax(decimal price, decimal taxRate)
{
return price * (1 + taxRate);
}
Regular Comments
Use regular comments for internal implementation explanations:
public void ProcessPayment()
{
// Check if payment provider is available before proceeding
if (!IsPaymentProviderOnline())
{
return;
}
// Calculate fees and discounts
var fees = CalculateFees();
// Send to payment processor
// TODO: Implement retry logic for failed attempts
}
Formatting Guidelines
Line Length
Try to keep lines under 100-120 characters for readability:
// Too long, hard to read
var result = database.Users.Where(u => u.Status == UserStatus.Active && u.CreatedDate > DateTime.Now.AddMonths(-1) && u.EmailConfirmed).OrderByDescending(u => u.LastLoginDate).ToList();
// Better: Split into multiple lines
var result = database.Users
.Where(u => u.Status == UserStatus.Active
&& u.CreatedDate > DateTime.Now.AddMonths(-1)
&& u.EmailConfirmed)
.OrderByDescending(u => u.LastLoginDate)
.ToList();
Spacing
Use spaces around operators for better readability:
// Good
int sum = a + b;
bool isValid = (count > 0) && (name != null);
// Avoid
int sum=a+b;
bool isValid=(count>0)&&(name!=null);
Real-World Example: Building a Task Manager
Let's apply these code style principles to a simple task management class:
using System;
using System.Collections.Generic;
using System.Linq;
namespace TaskManagement
{
/// <summary>
/// Manages a collection of tasks with prioritization capabilities.
/// </summary>
public class TaskManager
{
// Private fields with underscore prefix
private readonly List<Task> _tasks;
private int _completedCount;
// Properties with PascalCase
public int TaskCount => _tasks.Count;
public int CompletedCount => _completedCount;
// Constructor
public TaskManager()
{
_tasks = new List<Task>();
_completedCount = 0;
}
/// <summary>
/// Adds a new task to the task list.
/// </summary>
/// <param name="title">Title of the task</param>
/// <param name="priority">Priority level from 1 (highest) to 5 (lowest)</param>
/// <returns>The ID of the newly created task</returns>
public int AddTask(string title, int priority)
{
// Validate parameters
if (string.IsNullOrEmpty(title))
{
throw new ArgumentException("Task title cannot be empty", nameof(title));
}
if (priority < 1 || priority > 5)
{
throw new ArgumentOutOfRangeException(
nameof(priority),
"Priority must be between 1 and 5"
);
}
// Create and add the new task
var task = new Task
{
Id = _tasks.Count > 0 ? _tasks.Max(t => t.Id) + 1 : 1,
Title = title,
Priority = priority,
IsCompleted = false,
CreatedDate = DateTime.Now
};
_tasks.Add(task);
return task.Id;
}
/// <summary>
/// Marks a task as completed.
/// </summary>
/// <param name="taskId">ID of the task to complete</param>
/// <returns>True if the task was found and updated, false otherwise</returns>
public bool CompleteTask(int taskId)
{
var task = _tasks.FirstOrDefault(t => t.Id == taskId);
if (task == null)
{
return false;
}
if (!task.IsCompleted)
{
task.IsCompleted = true;
task.CompletedDate = DateTime.Now;
_completedCount++;
}
return true;
}
/// <summary>
/// Gets all high priority tasks (priority 1 or 2).
/// </summary>
/// <returns>A list of high priority tasks</returns>
public List<Task> GetHighPriorityTasks()
{
return _tasks
.Where(t => t.Priority <= 2 && !t.IsCompleted)
.OrderBy(t => t.Priority)
.ToList();
}
// Private Task class with proper naming and structure
private class Task
{
public int Id { get; set; }
public string Title { get; set; }
public int Priority { get; set; }
public bool IsCompleted { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime? CompletedDate { get; set; }
}
}
}
Using .editorconfig for Automatic Styling
Modern development often uses an .editorconfig
file to enforce consistent style. Here's a basic example:
# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true
# C# files
[*.cs]
# Indentation and spacing
indent_size = 4
indent_style = space
tab_width = 4
# New line preferences
end_of_line = crlf
insert_final_newline = true
# C# formatting rules
csharp_new_line_before_open_brace = all
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
Many IDEs, including Visual Studio and VS Code, automatically apply these styles when this file is present in your project.
Summary
Consistent code style improves readability and makes your C# code more professional. Key points to remember:
- Use Pascal Case for classes, methods, and properties
- Use camel case for local variables and parameters
- Use underscores for private fields
- Be consistent with braces and indentation
- Organize code files logically
- Comment your code appropriately
- Maintain consistent spacing and line lengths
By following these conventions, you'll write cleaner, more maintainable code that other developers will appreciate working with.
Additional Resources
Exercises
-
Convert the following code to follow proper C# code style:
csharpclass userdata {
public string firstname;
public string lastname;
public void printname(){
string fullname=firstname+" "+lastname;
Console.WriteLine(fullname);
}
} -
Create a simple
BankAccount
class following proper code style that includes:- Private fields for account balance and account number
- Properties for account holder name and account type
- Methods for deposit and withdrawal
- Appropriate XML documentation comments
-
Download and configure the StyleCop analyzer for your Visual Studio or VS Code environment and run it against your existing projects to identify style issues.
Happy coding with style!
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)