Estándares de Codificación y Convenciones de Nombres en C#

Hablaremos sobre convenciones de código y buenas prácticas.

Nombre del Objeto Notación Longitud Plural Prefijo Sufijo Abreviación Máscara de Caracteres Guiones Bajos
Nombre de namespace PascalCase 128 No No [A-z][0-9] No
Nombre de clase PascalCase 128 No No No [A-z][0-9] No
Nombre de constructor PascalCase 128 No No No [A-z][0-9] No
Nombre de método PascalCase 128 No No No [A-z][0-9] No
Argumentos de método camelCase 128 No No [A-z][0-9] No
Variables locales camelCase 50 No No [A-z][0-9] No
Nombre de constantes PascalCase 50 No No No No [A-z][0-9] No
Campo público PascalCase 50 No No [A-z][0-9] No
Campo privado _camelCase 50 No No _[A-z][0-9]
Nombre de propiedades PascalCase 50 No No [A-z][0-9] No
Nombre de delegado PascalCase 128 No No [A-z] No
Nombre de tipo enum PascalCase 128 No No No [A-z] No

1. Utiliza PascalCase para nombres de clases y métodos:

CSHARP
public class ClientActivity
{
  public void ClearStatistics()
  {
    //...
  }

  public void CalculateStatistics()
  {
    //...
  }
}

Por qué: es consistente con el Framework .NET de Microsoft y facilita la lectura.

2. Utiliza camelCase para argumentos de métodos y variables locales:

CSHARP
public class UserLog
{
  public void Add(LogEvent logEvent)
  {
    int itemCount = logEvent.Items.Count;
    // ...
  }
}

Por qué: es consistente con el Framework .NET de Microsoft y facilita la lectura.

3. No utilices notación húngara ni identificadores que indiquen el tipo

CSHARP
// Correcto
int counter;
string name;

// Evitar
int iCounter;
string strName;

Por qué: Visual Studio permite identificar fácilmente los tipos mediante tooltips. En general, evita incluir información de tipo en los identificadores.

4. No utilices MAYÚSCULAS COMPLETAS para constantes o variables readonly:

CSHARP
// Correcto
public const string ShippingType = "DropShip";

// Evitar
public const string SHIPPINGTYPE = "DropShip";

Por qué: es consistente con el Framework .NET de Microsoft. Las mayúsculas completas llaman demasiado la atención visualmente.

5. Utiliza nombres significativos para las variables

El siguiente ejemplo utiliza seattleCustomers para representar clientes ubicados en Seattle:

CSHARP
var seattleCustomers = from customer in customers
  where customer.City == "Seattle"
  select customer.Name;

Por qué: es consistente con el Framework .NET de Microsoft y facilita la lectura.

6. Evita abreviaciones

Excepciones: abreviaciones ampliamente utilizadas como Id, Xml, Ftp, Uri.

CSHARP
// Correcto
UserGroup userGroup;
Assignment employeeAssignment;

// Evitar
UserGroup usrGrp;
Assignment empAssignment;

// Excepciones
CustomerId customerId;
XmlDocument xmlDocument;
FtpHelper ftpHelper;
UriPart uriPart;

Por qué: evita abreviaciones inconsistentes y mejora la legibilidad.

7. Utiliza PascalCase o camelCase para abreviaciones de 3 caracteres o más

(Las abreviaciones de 2 caracteres se escriben completamente en mayúsculas cuando corresponde).

CSHARP
HtmlHelper htmlHelper;
FtpTransfer ftpTransfer, fastFtpTransfer;
UIControl uiControl, nextUIControl;

Por qué: es consistente con el Framework .NET de Microsoft. Las mayúsculas excesivas generan ruido visual.

8. No utilices guiones bajos en identificadores

Excepción: los campos privados pueden comenzar con _.

CSHARP
// Correcto
public DateTime clientAppointment;
public TimeSpan timeLeft;

// Evitar
public DateTime client_Appointment;
public TimeSpan time_Left;

// Excepción (campo de clase)
private DateTime _registrationDate;

Por qué: hace el código más natural de leer y evita problemas visuales con los subrayados.

9. Utiliza los alias de tipos de C# (int, float, string, etc.) para declaraciones locales, parámetros y miembros

Utiliza los nombres del Framework (Int32, String, etc.) cuando accedas a miembros estáticos del tipo.

CSHARP
// Correcto
string firstName;
int lastIndex;
bool isSaved;
string commaSeparatedNames = String.Join(", ", names);
int index = Int32.Parse(input);

// Evitar
String firstName;
Int32 lastIndex;
Boolean isSaved;
string commaSeparatedNames = string.Join(", ", names);
int index = int.Parse(input);

Por qué: hace el código más natural de leer y mantiene consistencia con .NET.

10. Utiliza var para declaraciones de variables locales

Excepción: tipos primitivos (int, string, double, etc.).

CSHARP
var stream = File.Create(path);
var customers = new Dictionary();

// Excepciones
int index = 100;
string timeSheet;
bool isCompleted;

Por qué: reduce ruido visual, especialmente con tipos genéricos complejos.

11. Utiliza sustantivos o frases nominales para nombrar clases

CSHARP
public class Employee
{
}

public class BusinessLocation
{
}

public class DocumentCollection
{
}

Por qué: son más fáciles de recordar y siguen las convenciones de .NET.

12. Prefija las interfaces con la letra I

Los nombres deben ser sustantivos o adjetivos.

CSHARP
public interface IShape
{
}

public interface IShapeCollection
{
}

public interface IGroupable
{
}

Por qué: es consistente con el Framework .NET de Microsoft.

13. Nombra los archivos fuente según su clase principal

Excepción: clases parciales (partial) que reflejan su propósito.

CSHARP
// Ubicado en Task.cs
public partial class Task
{
}

// Ubicado en Task.generated.cs
public partial class Task
{
}

Por qué: facilita la organización y mantiene juntas las clases parciales.

14. Organiza los namespaces con una estructura clara

CSHARP
namespace Company.Technology.Feature.Subnamespace
{
}

namespace Company.Product.Module.SubModule
{
}

namespace Product.Module.Component
{
}

namespace Product.Layer.Module.Group
{
}

Por qué: mantiene una buena organización de la base de código.

15. Alinea verticalmente las llaves

CSHARP
// Correcto
class Program
{
  static void Main(string[] args)
  {
    //...
  }
}

Por qué: aunque Microsoft utiliza otro estándar, muchos desarrolladores prefieren esta alineación por legibilidad.

16. Declara todas las variables miembro al inicio de la clase

Las variables estáticas deben ir primero.

CSHARP
public class Account
{
  public static string BankName;
  public static decimal Reserves;

  public string Number { get; set; }
  public DateTime DateOpened { get; set; }
  public DateTime DateClosed { get; set; }
  public decimal Balance { get; set; }

  // Constructor
  public Account()
  {
    // ...
  }
}

Por qué: evita tener que buscar declaraciones distribuidas por toda la clase.

17. Utiliza nombres singulares para enums

Excepción: enums de banderas (Flags).

CSHARP
// Correcto
public enum Color
{
  Red,
  Green,
  Blue,
  Yellow,
  Magenta,
  Cyan
}

// Excepción
[Flags]
public enum Dockings
{
  None = 0,
  Top = 1,
  Right = 2,
  Bottom = 4,
  Left = 8
}

Por qué: un enum representa un único valor. Los enums con Flags pueden contener varios valores simultáneamente.

18. No especifiques explícitamente el tipo subyacente ni los valores de un enum

Excepto para enums con Flags.

CSHARP
// No recomendado
public enum Direction : long
{
  North = 1,
  East = 2,
  South = 3,
  West = 4
}

// Correcto
public enum Direction
{
  North,
  East,
  South,
  West
}

Por qué: evita dependencias innecesarias en valores o tipos concretos.

19. No utilices el sufijo Enum en nombres de enums

CSHARP
// No recomendado
public enum CoinEnum
{
  Penny,
  Nickel,
  Dime,
  Quarter,
  Dollar
}

// Correcto
public enum Coin
{
  Penny,
  Nickel,
  Dime,
  Quarter,
  Dollar
}

Por qué: evita indicadores de tipo redundantes.

20. No utilices los sufijos Flag o Flags en nombres de enums

CSHARP
// No recomendado
[Flags]
public enum DockingsFlags
{
  None = 0,
  Top = 1,
  Right = 2,
  Bottom = 4,
  Left = 8
}

// Correcto
[Flags]
public enum Dockings
{
  None = 0,
  Top = 1,
  Right = 2,
  Bottom = 4,
  Left = 8
}

Por qué: evita indicadores de tipo redundantes.

21. Utiliza el sufijo EventArgs al crear clases que contienen información de eventos

CSHARP
public class BarcodeReadEventArgs : System.EventArgs
{
}

Por qué: es consistente con el Framework .NET de Microsoft y fácil de identificar.

22. Utiliza el sufijo EventHandler para los delegados de eventos

CSHARP
public delegate void ReadBarcodeEventHandler(
    object sender,
    ReadBarcodeEventArgs e);

Por qué: es consistente con el Framework .NET de Microsoft y fácil de identificar.

23. No crees parámetros que solo se diferencien por mayúsculas y minúsculas

CSHARP
// Evitar
private void MyFunction(string name, string Name)
{
  //...
}

Por qué: dificulta la lectura y puede generar errores o confusión.

24. Utiliza los parámetros sender y e en los manejadores de eventos

CSHARP
public void ReadBarcodeEventHandler(
    object sender,
    ReadBarcodeEventArgs e)
{
  //...
}

Por qué: es consistente con las convenciones estándar de .NET.

25. Utiliza el sufijo Exception al crear clases de excepción

CSHARP
public class BarcodeReadException : System.Exception
{
}

Por qué: facilita identificar excepciones personalizadas.

26. Utiliza prefijos como Is, Has, Can, Any para identificadores booleanos

CSHARP
public static bool IsNullOrEmpty(string value)
{
    return value == null || value.Length == 0;
}

Por qué: mejora la legibilidad y expresa claramente una condición booleana.

27. Utiliza argumentos nombrados en las llamadas a métodos

Al llamar a un método, pasa el nombre del parámetro seguido de : y su valor.

CSHARP
// Método
public void DoSomething(string foo, int bar)
{
    ...
}

// Evitar
DoSomething("someString", 1);

// Correcto
DoSomething(foo: "someString", bar: 1);

Por qué: mejora la legibilidad y evita depender del orden de los parámetros.

#Referencias Oficiales

  1. MSDN - General Naming Conventions
  2. DoFactory - C# Coding Standards and Naming Conventions
  3. MSDN - Naming Guidelines
  4. MSDN - Framework Design Guidelines
  5. Microsoft Learn - Common C# Coding Conventions
  6. GitHub - C# Coding Style