C# Code Style Guidelines
Convenciones de codigo C# obligatorias para todos los proyectos del ecosistema Dinaup.
Configuracion de proyecto
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>disable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<Using Include="Dinaup.extensions" Static="true" />
</ItemGroup>
Cultura invariante
Todos los proyectos Dinaup ignoran la cultura del sistema. Todos los hilos se configuran con en-US para garantizar comportamiento consistente en cualquier entorno. Los separadores decimales, formatos de fecha y parsing numerico funcionan identicamente en cualquier servidor.
DateTime siempre en UTC. Sin horas locales, sin conversiones de zona horaria. Todas las fechas se almacenan, procesan y transmiten en UTC.
Practicas obligatorias
No usar tipos nullable
Usar valores por defecto para representar estados "vacios":
- DateTime vacio:
DateTime.MinValue - Decimal vacio:
0 - Guid vacio:
Guid.Empty
No devolver objetos anonimos
Siempre usar DTOs tipados en controladores y servicios:
// Correcto
return Ok(new AppInfoDTO { Version = "2", Revision = "2", Status = "OK" });
// Incorrecto
return Ok(new { version = "2", revision = "2" });
No usar ! (operador de negacion)
// Correcto
if (user.Enabled == false) return;
// Incorrecto
if (!user.Enabled) return;
Colecciones: usar extension methods
// Correcto
if (_items.IsNotEmpty()) ProcessItems();
// Incorrecto
if (_items?.Count > 0) ProcessItems();
Comparacion de Guid
// Correcto
if (f.NextRowId.IsEmpty()) return;
if (prevId.IsNotEmpty()) Process(prevId);
// Incorrecto
if (f.NextRowId == Guid.Empty) return;
Usar decimal para valores numericos
// Correcto
decimal price = 19.99m;
// Incorrecto - float y double causan errores de precision
float price = 19.99f;
Extension methods
Conversion de tipos
| Metodo | Descripcion | Ejemplo |
|---|---|---|
.STR() | Conversion a string (decimal en formato US, Guid.Empty devuelve "", bool devuelve "1"/"0") | 12.5m.STR() devuelve "12.5" |
.INT([default]) | Conversion a int | "123".INT() devuelve 123 |
.DEC([default]) | Conversion a decimal | "12.5".DEC() devuelve 12.5 |
.BOOL() | Conversion a bool ("1","si","yes","true","on" son true) | "si".BOOL() devuelve true |
Validacion
| Metodo | Descripcion |
|---|---|
.IsNotNull() | Referencia no es null |
.IsNull() | Referencia es null |
.IsEmpty() | Vacio: Guid.Empty, "", DateTime.MinValue, 0, coleccion vacia |
.IsNotEmpty() | Opuesto de IsEmpty |
Strings
| Metodo | Descripcion |
|---|---|
.EqualsIgnoreCase() | Comparacion case-insensitive |
.LikeM() | Pattern matching estilo LIKE (case-sensitive) |
.LikeMIgnoreCase() | Pattern matching estilo LIKE (case-insensitive) |
.ContainsWebSearchMode(query) | Busqueda multi-palabra: cada palabra del query debe estar presente |
Diccionarios
// Getter seguro que nunca lanza excepcion
MyDictionary.GetM("key") // null si no existe
MyDictionary.GetM("key", "default") // "default" si no existe
Blazor: propiedades de componentes
Solo usar comillas para literales string. Usar @ para expresiones:
// Correcto
<DataGrid Data=@x.Data />
// Incorrecto
<DataGrid Data="x.Data" />