Documentación de C#
Referencia concisa y basada en ejemplos de C#. Lee el concepto, mira el código y practícalo en un recorrido de Coddy.
Inicia un recorrido guiado de C#Primeros pasos
- Qué es C#C# es un lenguaje de propósito general con tipado estático, creado por Microsoft, que se ejecuta sobre .NET. Para qué se usa, cómo se relaciona con .NET, qué añadió cada versión y cómo se organiza un programa en C#.
- Hola mundoTu primer programa en C# línea a línea: el método Main, Console.WriteLine y Write, leer la entrada con Console.ReadLine, los comentarios, crear y ejecutar un proyecto con la CLI de dotnet, y las instrucciones de nivel superior.
- C# vs JavaC# y Java se parecen y resuelven problemas similares. Las diferencias reales están en las propiedades, los tipos de valor, los genéricos, LINQ frente a los streams, async, las excepciones y los ecosistemas que los rodean. Una comparación lado a lado con código.
- C# vs C++C# es un lenguaje gestionado con recolector de basura; C++ compila a código nativo y te da control manual sobre la memoria. Cómo se nota esa diferencia en la seguridad, el rendimiento, los motores de juego, el modelo de compilación y la dificultad de aprender cada uno.
- Namespaces y usingCómo organizan los namespaces de C# los tipos y cómo los importa la directiva using: alias, using static, nombres completos, resolver referencias ambiguas, usings globales y namespaces con ámbito de archivo.
Fundamentos
- VariablesCómo declarar y asignar variables en C#, cuándo var es buena idea y cuándo no, cómo funciona el ámbito, la diferencia entre const, readonly y static readonly, las convenciones de nombres y el error de variable sin asignar.
- Tipos de datosTodos los tipos incorporados de C# con su tamaño, su rango y el sufijo de sus literales, la diferencia entre tipos de valor y de referencia, por qué decimal es el tipo para el dinero, el desbordamiento de enteros y checked, y los valores por defecto.
- String a intCómo convertir un string a int en C# con int.Parse, int.TryParse y Convert.ToInt32, cómo funcionan los casts implícitos y explícitos, por qué el cast de un double trunca, los operadores as e is, y por qué "1.5" puede leerse como 15.
- OperadoresLos operadores de C# con su comportamiento exacto: la división entera, el operador módulo con números negativos, el incremento y la asignación compuesta, la comparación, la lógica de cortocircuito, los operadores bit a bit, los operadores de null y una tabla de precedencia.
- StringsCómo funcionan los strings en C#: inmutabilidad, Length e índices, comparar con ==, Equals y string.Compare, caracteres de escape, strings literales con @ y texto multilínea, literales de string sin procesar, comprobaciones de null y vacío, y recorrer los caracteres.
- SubstringCómo funciona String.Substring en C#: los argumentos de índice inicial y longitud, la ArgumentOutOfRangeException y cómo evitarla, extraer texto alrededor de los resultados de IndexOf, tomar los n primeros o últimos caracteres, y el operador de rango de C# 8.
- Interpolación de stringsCómo funciona la interpolación de strings $"..." en C#: expresiones entre llaves, especificadores de formato como F2, N0, C, D5 y X, alineación para tablas, escapar llaves, string.Format y el formato compuesto, strings interpolados literales y sin procesar, y dar formato para una cultura concreta.
- Métodos de stringLos métodos de String que usas a diario en C#: Split con varios separadores y opciones, Replace, Contains y la búsqueda sin distinguir mayúsculas, IndexOf y LastIndexOf, StartsWith y EndsWith, Trim, ToUpper y ToLower, PadLeft, Join, Concat e invertir un string.
- StringBuilderPor qué concatenar strings una y otra vez en un bucle es lento en C#, y cómo lo resuelve StringBuilder: Append, AppendLine, AppendFormat, Insert, Remove, Replace, la capacidad, y cuándo la concatenación simple o string.Join son mejor opción.
- Números aleatoriosCómo generar números aleatorios en C# con la clase Random: Next y su límite superior exclusivo, doubles aleatorios en un rango, semillas para obtener resultados reproducibles, elegir un elemento al azar, mezclar una lista, la trampa de new Random en un bucle, y números criptográficamente seguros.
- DateTimeTrabajar con fechas y horas en C#: crear valores DateTime, Now frente a UtcNow y Today, sumar días y meses, restar para obtener un TimeSpan, TotalHours frente a Hours, comparar fechas, DayOfWeek, parsear con ParseExact y TryParse, DateTimeOffset y DateOnly.
- Formato de DateTimeCómo dar formato a un DateTime como string en C#: los strings de formato estándar (d, D, o, s, u, t), patrones personalizados como yyyy-MM-dd HH:mm:ss, una tabla completa de especificadores, cómo cambia la salida con la cultura, ISO 8601 de ida y vuelta con "o", y los errores de mm frente a MM y hh frente a HH.
Control de flujo
- if elseCómo funcionan if, else if y else en C#: por qué las condiciones deben ser bool, cómo combinar pruebas con &&, || y !, cuándo importan las llaves, cláusulas de guarda en lugar de anidar en profundidad, y los errores de = frente a == y del punto y coma suelto.
- Sentencia switchCómo funciona la sentencia switch en C#: switch sobre valores int, string, char y enum, por qué cada case necesita break (error CS0163), apilar etiquetas case para varios valores, goto case, default, la distinción entre mayúsculas y minúsculas en strings y las etiquetas case con patrones y when.
- Expresión switchLa expresión switch de C# 8 convierte un valor en un resultado con brazos de patrones en lugar de case y break. Sintaxis, el descarte _, patrones de propiedad, de tupla y relacionales, and/or/not, guardas when, avisos de exhaustividad y SwitchExpressionException, con equivalentes ejecutables en C# 7.
- Operador ternarioEl operador condicional de C# condition ? a : b elige uno de dos valores. Cómo se evalúa, por qué las dos ramas necesitan un tipo común (CS0173) y el cast que lo arregla, ternarios anidados, paréntesis en la interpolación de strings y cuándo ?? y ?. lo expresan mejor.
- Bucle forCómo funciona el bucle for en C#: el inicializador, la condición y el iterador, contar hacia atrás y con saltos, varias variables de bucle, recorrer arrays por índice, bucles anidados, for(;;), y los bugs de desfase por uno y de borrar mientras se itera.
- Bucle foreachCómo funciona foreach en C#: recorrer arrays, listas, strings y diccionarios (KeyValuePair y deconstrucción), obtener el índice, por qué la variable del bucle es de solo lectura, la InvalidOperationException "Collection was modified" y cómo evitarla, y qué necesita un tipo para usarse en foreach.
- Bucle whileCómo funcionan los bucles while y do while en C#: la condición comprobada antes o después del cuerpo, leer la entrada hasta un valor centinela o hasta el final, while (true) con break, y los errores de bucle infinito en los que cae mucha gente.
- break y continueCómo funcionan break, continue y goto en C#: terminar un bucle antes de tiempo, saltar una iteración, break dentro de un switch, tres formas de salir de bucles anidados (una variable indicadora, goto o un método con return), y el bug del bucle infinito con continue dentro de un while.
Métodos y delegados
- MétodosCómo declarar y llamar a métodos en C#: tipos de retorno y void, parámetros, métodos con cuerpo de expresión, devolver varios valores con una tupla, sobrecarga, arrays params, métodos static frente a métodos de instancia, el método Main, recursividad y funciones locales.
- Parámetros opcionalesCómo funcionan los parámetros opcionales y los argumentos con nombre en C#: valores por defecto y la regla de la constante en tiempo de compilación, el orden de los parámetros, saltarse argumentos por nombre, parámetros opcionales frente a sobrecargas, atributos de información del llamador y la trampa de versiones de los valores por defecto grabados en quien llama.
- ref y outCómo funcionan los parámetros ref, out e in en C#: pasar una variable en lugar de una copia, out para resultados extra y el patrón TryParse, out var, parámetros in de solo lectura, las reglas de asignación definitiva y qué cambia cuando el argumento es un tipo de referencia.
- Expresiones lambdaCómo funcionan las expresiones lambda en C#: la sintaxis => en todas sus formas, guardar lambdas en Func y Action, pasarlas a métodos y a LINQ, lambdas de sentencias, closures sobre variables capturadas y el bug de captura del bucle for que foreach no tiene.
- DelegadosQué es un delegado en C# y cómo se usa: declarar un tipo delegado, crearlo a partir de un método, una lambda o un método anónimo, invocarlo, delegados como callbacks, delegados multicast con += y -=, comprobaciones de null con ?.Invoke, y cómo se relacionan los delegados con Func, Action y los eventos.
- Func y ActionCómo funcionan Func y Action en C#: Func<T, TResult> para funciones que devuelven un valor, Action<T> para las que no, Predicate y Comparison, pasar y devolver funciones, un diccionario de comandos, lambdas async y cuándo declarar tu propio delegado.
- EventosCómo funcionan los eventos en C#: declarar un evento con EventHandler y EventHandler<T>, clases EventArgs propias, suscribirse y cancelar la suscripción con += y -=, lanzar un evento de forma segura con ?.Invoke, por qué un evento es mejor que un campo delegado público, y la fuga de memoria que provoca una cancelación de suscripción olvidada.
- Métodos de extensiónCómo funcionan los métodos de extensión en C#: un método static en una clase static con this en el primer parámetro, llamarlo como un método de instancia, extender string, enums e IEnumerable<T>, cómo se construye LINQ con ellos, por qué ganan los métodos de instancia, receptores null y la directiva using que necesitan.
Colecciones y LINQ
- ArraysUn array de C# es un bloque de tamaño fijo con elementos de un solo tipo. Aprende a declarar e inicializar arrays, leer Length, ordenar y buscar con la clase Array, copiarlos de forma segura y trabajar con arrays 2D y arrays escalonados.
- ListList<T> es el array que crece de C#. Aprende a crear una lista, añadir e insertar elementos, eliminar por valor, por índice o por condición, buscar con Contains y Find, ordenar por una propiedad y evitar el error de cambiar una lista dentro de un foreach.
- DictionaryDictionary<TKey, TValue> asocia claves a valores con búsquedas rápidas. Aprende a añadir y actualizar entradas, leer de forma segura con TryGetValue, recorrer las entradas KeyValuePair, contar apariciones, ignorar mayúsculas en las claves y mantener las claves ordenadas con SortedDictionary.
- HashSetHashSet<T> contiene elementos únicos y responde a Contains en tiempo constante. Aprende cómo Add informa de los duplicados, cómo quitar duplicados de una lista, cómo unir, intersecar y restar conjuntos, y cómo hacer que un conjunto compare tus propios objetos por valor.
- QueueQueue<T> es una colección en la que el primero que entra es el primero que sale: los elementos salen en el orden en que llegaron. Aprende Enqueue, Dequeue y Peek, la excepción de la cola vacía y TryDequeue, la búsqueda en anchura con una cola, y cuándo recurrir a ConcurrentQueue o PriorityQueue.
- StackStack<T> es una colección en la que el último que entra es el primero que sale: el elemento añadido más recientemente sale primero. Aprende Push, Pop y Peek, la excepción de la pila vacía y TryPop, por qué una pila se enumera al revés, y dos usos clásicos: un historial para deshacer y comprobar paréntesis equilibrados.
- TuplasUna tupla de C# agrupa unos pocos valores en uno solo sin declarar un tipo. Aprende la sintaxis de las tuplas de valor, los elementos con nombre, devolver varios valores desde un método, deconstruir con var (a, b), tuplas como claves de un diccionario y en qué se diferencia ValueTuple del antiguo System.Tuple.
- LINQLINQ añade operadores de consulta a todas las colecciones de C#. Aprende la sintaxis de métodos y la sintaxis de consulta, filtrar con Where, proyectar con Select, ordenar con OrderBy y ThenBy, agrupar con GroupBy, la trampa de First frente a FirstOrDefault, los agregados y cómo la ejecución diferida cambia el momento en que se ejecuta tu consulta.
- IEnumerable y yieldIEnumerable<T> es la interfaz que hay detrás de foreach y LINQ, y yield return es la forma más sencilla de implementarla. Aprende cómo se relaciona IEnumerable con ICollection y List, cómo se ejecuta paso a paso un método iterador, yield break, las secuencias infinitas y las trampas de la evaluación perezosa.
Clases y tipos
- Clases y objetosCómo declarar una clase en C#, darle campos y métodos, crear objetos con new, y qué significa que una clase sea un tipo de referencia: objetos compartidos, null y NullReferenceException, ToString e inicializadores de objetos.
- ConstructoresCómo funcionan los constructores en C#: el constructor por defecto implícito y cuándo desaparece, constructores con parámetros y sobrecargados, encadenar con this(...) y base(...), el orden en que se ejecuta todo, los constructores static y privados, y los constructores primarios de C# 12.
- PropiedadesCómo funcionan las propiedades en C#: los accesores get y set sobre un campo de respaldo, las propiedades automáticas, private set y las propiedades de solo lectura, las propiedades calculadas, la validación en los setters, y las palabras clave init y required de C# 9 y 11.
- Palabra clave staticQué significa static en C#: miembros que pertenecen al tipo en lugar de a un objeto, estado compartido entre instancias, métodos static y clases static, constructores static, const frente a static readonly, using static y el error CS0120.
- Modificadores de accesoLos seis modificadores de acceso de C# (public, private, protected, internal, protected internal, private protected), qué permite cada uno, los valores por defecto cuando no escribes ninguno y los errores de compilación que producen.
- HerenciaCómo funciona la herencia de clases en C#: derivar con dos puntos, qué se hereda y qué no, llamar a la clase base con base, virtual y override, ocultar con new (y la salida que sorprende a todo el mundo), sealed, el polimorfismo y las conversiones hacia arriba y hacia abajo en una jerarquía.
- Clases abstractasQué es una clase abstracta en C#: una clase base que no puede instanciarse y que puede declarar miembros abstractos que sus clases derivadas deben implementar. Incluye métodos y propiedades abstractos, constructores, el patrón template method y cuándo elegir una interfaz en su lugar.
- InterfacesCómo funcionan las interfaces en C#: declarar una, implementarla en clases y structs, usar la interfaz como tipo, implementar varias a la vez, la implementación explícita, las interfaces del framework que más implementarás (IComparable<T>, IEnumerable<T>, IDisposable) y los métodos de interfaz por defecto de C# 8.
- StructsCómo funcionan los structs en C#: la semántica de valor y la copia al asignar, el error al modificar una List<T>, las reglas de los constructores, la igualdad, el boxing, readonly struct y record struct, y una comparación entre struct y class con pautas sobre cuándo un struct es la opción correcta.
- EnumsCómo funcionan los enums en C#: declarar constantes con nombre, los valores enteros subyacentes y el cast, convertir un enum a string y un string a enum con Parse y TryParse, listar todos los valores, [Flags] con operadores bit a bit y HasFlag, switch sobre un enum y el manejo de valores no definidos.
- RecordsQué son los records de C# (C# 9 y posteriores): la sintaxis posicional, los miembros que genera el compilador, la igualdad por valor, las copias no destructivas con with, el ToString incorporado, record struct de C# 10, la herencia entre records y la clase equivalente escrita a mano.
- GenéricosCómo funcionan los genéricos en C#: escribir clases y métodos genéricos con parámetros de tipo, la inferencia de tipos, las restricciones con where (class, struct, new(), clases base, interfaces), default(T), los miembros static por tipo y la covarianza con IEnumerable<out T>.
- Tipos nullableTodo sobre null en C#: los tipos de valor nullable (int?, Nullable<T>) con HasValue, Value y GetValueOrDefault, los operadores de fusión de null ?? y ??=, el operador condicional null ?., las comprobaciones de null y los tipos de referencia nullable (string?) de C# 8.
- Pattern matchingCómo funciona el pattern matching en C#: el operador is con patrones de tipo y de constante, sentencias switch con patrones en los case y when, expresiones switch, patrones de propiedad, de tupla y posicionales, patrones relacionales y lógicos (and, or, not), patrones de lista, y qué versión de C# añadió cada uno.
Excepciones
- Try Catchtry, catch y finally son la forma en que C# maneja las excepciones. Aprende cómo sube una excepción por la pila de llamadas, cómo capturar tipos de excepción concretos en el orden correcto, filtrar con when, limpiar en finally, volver a lanzar con throw; sin perder la traza de la pila y qué excepciones no hay que capturar.
- Lanzar excepcionesCómo y cuándo lanzar excepciones en C#. Aprende la sentencia throw, qué tipo de excepción incorporado encaja con cada error, las expresiones throw con ?? y ?:, los métodos auxiliares ThrowIfNull, y cómo escribir una clase de excepción propia con sus propios datos y una excepción interna.
- Sentencia usingLa sentencia using garantiza que se llama a Dispose en archivos, streams, conexiones y demás objetos IDisposable, incluso cuando se lanza una excepción. Aprende en qué se compila, en qué orden se liberan los objetos, la declaración using de C# 8 y cómo implementar IDisposable en tu propia clase.
Asincronía e hilos
- Async Awaitasync y await permiten que el código C# espere operaciones lentas sin bloquear un hilo. Aprende cómo se ejecuta un método async, Task y Task<T>, ejecutar a la vez operaciones independientes con Task.WhenAll, las excepciones en código async, y por qué async void y .Result provocan bugs e interbloqueos.
- TareasTask es la unidad de trabajo asíncrono y paralelo en .NET. Aprende Task.Run para el trabajo que depende de la CPU, leer resultados, combinar tareas con WhenAll y WhenAny, continuaciones, cancelar con CancellationToken, en qué se diferencia un Task de un Thread y cuándo encaja mejor Parallel.For.
- LockLa sentencia lock permite que solo un hilo a la vez ejecute un bloque de código. Mira cómo una condición de carrera corrompe un contador, arréglalo con lock, aprende sobre qué objeto bloquear, usa Interlocked para contadores sencillos, evita los interbloqueos por el orden de los locks y usa SemaphoreSlim cuando el código de dentro hace await.
- TimerC# tiene varias clases de temporizador y se comportan de forma distinta. Aprende cuándo usar System.Threading.Timer, System.Timers.Timer, PeriodicTimer o un temporizador de interfaz, cómo iniciarlos y detenerlos, por qué los callbacks se ejecutan en el pool de hilos y pueden solaparse, por qué un temporizador debe seguir referenciado y cómo medir el tiempo transcurrido con Stopwatch.
Archivos, JSON y más
- Leer y escribir archivosCómo escribir en un archivo y leer un archivo en C#: File.WriteAllText, ReadAllText, AppendAllText, WriteAllLines y ReadAllLines para archivos completos, StreamWriter y StreamReader para los grandes, rutas con Path.Combine, directorios, codificaciones y las excepciones que tiene que manejar el código que trabaja con archivos.
- JSONCómo trabajar con JSON en C# usando System.Text.Json: JsonSerializer.Serialize y Deserialize, salida en camelCase e indentada, atributos como JsonPropertyName y JsonIgnore, enums como strings, leer JSON sin clases con JsonDocument y JsonNode, los errores y la comparación con Newtonsoft.Json.
- RegexCómo usar expresiones regulares en C# con System.Text.RegularExpressions: IsMatch, Match y Matches, grupos numerados y con nombre, Replace con sustituciones y con una lambda, Split, RegexOptions, strings literales para los patrones, validar entradas, tiempos límite y el atributo GeneratedRegex de .NET 7.
- Reflexión y atributosCómo funciona la reflexión en C#: objetos Type a partir de typeof y GetType, leer y asignar propiedades, llamar a métodos por su nombre, crear instancias, y los atributos: los incorporados como Obsolete, declarar los tuyos y leerlos en tiempo de ejecución. Además, lo que cuesta la reflexión.