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:
class 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!
💡 Found a typo or mistake? Click "Edit this page" to suggest a correction. Your feedback is greatly appreciated!