| name | csharp |
| description | Google's official C# style guide. Covers naming conventions, formatting, LINQ, async/await, XML documentation, and .NET best practices. |
Google C# Style Guide
Official Google C# coding standards for consistent, maintainable .NET code.
Golden Rules
- Follow .NET naming conventions — PascalCase for public members
- Use async/await for asynchronous operations
- LINQ for collections — prefer declarative over imperative
- XML documentation for public APIs
- Use
var when type is obvious from right side
- Prefer expression-bodied members when concise
- Use nullable reference types (C# 8.0+)
Quick Reference
Naming Conventions
| Element | Convention | Example |
|---|
| Classes/Interfaces | PascalCase | UserService, IRepository |
| Methods | PascalCase | GetUserById |
| Properties | PascalCase | UserCount |
| Local variables | camelCase | userCount |
| Constants | PascalCase | MaxRetries |
| Private fields | _camelCase | _userId |
| Parameters | camelCase | userId |
| Enums | PascalCase | Direction |
Variables and Types
var users = new List<User>();
var count = users.Count;
IEnumerable<User> result = GetUsers();
string? optionalName = null;
string requiredName = "Alice";
Properties and Fields
public string Name { get; set; }
public int Count { get; private set; }
private readonly string _connectionString;
private int _retryCount;
public string FullName => $"{FirstName} {LastName}";
Methods and Expressions
public string GetDisplayName() => $"{FirstName} {LastName}";
public async Task<User> GetUserAsync(int id)
{
var user = await _repository.FindAsync(id);
return user ?? throw new NotFoundException(id);
}
Async/Await
public async Task<IEnumerable<User>> GetActiveUsersAsync()
{
return await _db.Users
.Where(u => u.IsActive)
.ToListAsync();
}
var result = await SomeAsyncMethod().ConfigureAwait(false);
var result = SomeAsyncMethod().Result;
LINQ
var activeUsers = users
.Where(u => u.IsActive)
.OrderBy(u => u.LastName)
.Select(u => new UserDto(u.Id, u.Name))
.ToList();
var result = from u in users
join r in roles on u.RoleId equals r.Id
where u.IsActive
select new { u.Name, r.Title };
XML Documentation
public Task<User?> GetUserByIdAsync(int id)
{
}
Interfaces and Dependency Injection
public class UserService
{
private readonly IUserRepository _repository;
public UserService(IUserRepository repository)
{
_repository = repository;
}
}
Common Mistakes
| Mistake | Correct Approach |
|---|
Blocking on async (.Result, .Wait()) | Use async/await all the way |
| Missing XML docs on public API | Document with /// XML comments |
public fields | Use properties with get/set |
| Ignoring nullability | Enable <Nullable>enable</Nullable> |
| Imperative loops for collections | Use LINQ |
| Magic strings | Use nameof() or constants |
Catching Exception broadly | Catch specific exception types |
When to Use This Guide
- Writing new C# code
- Refactoring existing C#
- Code reviews
- Setting up
.editorconfig rules
- Onboarding new team members
Install
npx skills add testdino-hq/google-styleguides-skills/csharp
Full Guide
See csharp.md for complete details, examples, and edge cases.