En C#, usa is y is not para comprobaciones de tipo más legibles y coincidencias de patrones.
// Enfoque antiguo (usando "as" y comprobación de null)
object obj = "¡Hola, mundo!";
if (obj is string)
{
Console.WriteLine(((string)obj).ToUpper()); // ¡HOLA, MUNDO!
}
// Enfoque recomendado (usando is)
if (obj is string str)
{
Console.WriteLine(str.ToUpper()); // ¡HOLA, MUNDO!
}
// Usando "is not" para la negación
if (obj is not int)
{
Console.WriteLine("No es un entero");
}
En C#, Contains sirve para comprobar un valor exacto. Para comprobar una condición, es mejor usar Any(x => ...).
// Contains: para un valor exacto
var ids = new List<int> { 10, 20, 30 };
bool has20 = ids.Contains(20);
// Any: para una condición
bool hasOver25 = ids.Any(x => x > 25);
Console.WriteLine(has20); // True
Console.WriteLine(hasOver25); // True
En C#, FirstOrDefault() puede devolver null. Comprueba siempre el resultado antes de usarlo para evitar errores.
// Uso arriesgado
var user = users.FirstOrDefault();
Console.WriteLine(user.Name); // puede causar un error
// Uso seguro
var safeUser = users.FirstOrDefault();
if (safeUser != null)
{
Console.WriteLine(safeUser.Name);
}
En C#, el operador null-coalescing (??) permite asignar un valor predeterminado cuando una variable es null.
string? userName = null;
// Forma antigua
string name1 = userName != null ? userName : "Invitado";
// Forma recomendada
string name2 = userName ?? "Invitado";
Console.WriteLine(name1); // Invitado
Console.WriteLine(name2); // Invitado
En C#, usa Any() en lugar de comprobar Count > 0 para saber si una colección tiene elementos. Es más legible y a menudo más eficiente.
// Menos legible
if (items.Count > 0)
{
Console.WriteLine("Hay elementos");
}
// Uso recomendado
if (items.Any())
{
Console.WriteLine("Hay elementos");
}
En C#, usa class cuando los objetos se identifican por su identidad. Usa record cuando se identifican por sus valores.
// class: basado en identidad
class User
{
public string Name { get; set; }
public int Age { get; set; }
}
var u1 = new User { Name = "Carlos", Age = 30 };
var u2 = new User { Name = "Carlos", Age = 30 };
Console.WriteLine(u1 == u2); // False
// record: basado en valores
record UserRecord(string Name, int Age);
var r1 = new UserRecord("Carlos", 30);
var r2 = new UserRecord("Carlos", 30);
Console.WriteLine(r1 == r2); // True
En C#, los valores const son fijos en tiempo de compilación, mientras que los valores readonly pueden asignarse en tiempo de ejecución, normalmente en el constructor.
// const: el valor debe conocerse en compilación
public const int MaxItems = 10;
// readonly: el valor se asigna en ejecución
public readonly int Timeout;
public Settings()
{
Timeout = GetTimeoutFromConfig();
}
En C#, el operador ??= asigna un valor solo cuando la variable no tiene valor (null). Si ya tiene un valor, este se mantiene.
string? title = null;
// Se asigna un valor solo si no existe
title ??= "Sin título";
Console.WriteLine(title); // Sin título
// Como ya existe un valor, no hay cambios
title ??= "Nuevo título";
Console.WriteLine(title); // Sin título
En C#, usa IEnumerable<T> cuando solo necesitas leer y recorrer datos. Usa List<T> cuando necesitas agregar, eliminar o acceder a elementos por índice.
// Solo lectura: recorrer
IEnumerable<int> numbers = new[] { 10, 20, 30 };
foreach (var n in numbers)
{
Console.WriteLine(n);
}
// Lista: modificar o acceder por índice
List<int> list = new List<int> { 10, 20, 30 };
list.Add(40);
Console.WriteLine(list[0]); // 10
En C#, usa TryParse en lugar de Parse al convertir datos del usuario o externos para evitar errores en tiempo de ejecución.
// Uso arriesgado
int age = int.Parse(input);
// Uso seguro
if (int.TryParse(input, out int result))
{
Console.WriteLine(result);
}
else
{
Console.WriteLine("Número inválido");
}