Domina C# desde cero
400 lecciones, 40 capítulos, ejecutables en vivo (.NET 8). Fundamentos → control de flujo → loops → métodos → clases → herencia → colecciones → excepciones → generics → delegates + events → regex → async/await → structs/enums/records — con capstones reales en cada capítulo (Calculadora, Quiz App, Rocket Launch, Weather Simulator, BankAccount, Shape Zoo, Inventory Tracker, Resource Pool, Typed Bag, Stock Monitor, Log Parser, Download Aggregator, Vector2D). Cada lección lleva prosa, ejemplos corribles, visualizaciones SVG, callouts de pitfalls/deeper/tips/FAQ, y práctica graduada vía stdin/stdout.
Aprendamos juntos.
Pregúntame sobre este curso o por dónde empezar.
Hello World → top-level → variables → I/O → conversión → operadores → strings → errores → Calculadora
- Paso 1
Hello, World — tu primer programa en C#
Cada lenguaje tiene su tradición: el primer programa que escribes imprime "Hello, World" en la pantalla. En C#, esa únic…
Empezar lección - Paso 2
Directivas using, espacios de nombres y comentarios
La Base Class Library de .NET es enorme. Dentro de ella viven miles de tipos: Console, Math, DateTime, File, Random, Lis…
Empezar lección - Paso 3
Variables y el tipo string
Una variable es un espacio con nombre en la memoria que guarda un valor. Una vez que le pones nombre a ese espacio, pued…
Empezar lección - Paso 4
Entrada por consola — hablar con el usuario
Hasta ahora nuestros programas han sido monólogos: nosotros imprimimos y el usuario lee. Un programa que recibe entrada …
Empezar lección - Paso 5
Tipos numéricos — int, double, decimal, char
Los strings son ideales para texto, pero la mayoría de los programas tarde o temprano tienen que contar, medir o calcula…
Empezar lección - Paso 6
Conversión de tipos — cast, Parse, Convert, TryParse
C# es estricto con los tipos. No puedes asignar un double a un int por accidente, ni sumar un string a un número. Esa ri…
Empezar lección - Paso 7
Operadores, matemáticas y el orden de evaluación
La aritmética en C# usa los mismos operadores que conoces desde la escuela: + (más), - (menos), * (por), / (dividido ent…
Empezar lección - Paso 8
Formato de strings — interpolación, secuencias de escape, raw strings
Ya conocimos a la herramienta estrella, la interpolación: $"Hello, {name}!". Puedes hacer más que insertar variables. To…
Empezar lección - Paso 9
Errores en tiempo de compilación vs. en tiempo de ejecución
El código C# tiene que pasar por dos filtros antes de hacer algo útil. El primero es el compilador: comprueba que tu cód…
Empezar lección - Paso 10
Capstone — la calculadora de sumas
Es hora de combinar todo el capítulo. La calculadora de sumas es un pequeño programa que lee dos números del usuario, va…
Empezar lección
booleanos → if/else → operadores lógicos → cadenas else-if → anidado + scope → ternario → switch → switch expression → decisiones con strings → Quiz App
- Paso 11
Booleanos y operadores de comparación
Todo programa interesante tarde o temprano tiene que tomar una decisión: ¿imprimo el mensaje de éxito o el de error? ¿Si…
Empezar lección - Paso 12
if y else — elegir un camino
La sentencia if es la base de todo programa. Recibe un bool y, si ese bool es true, ejecuta el bloque de código que le s…
Empezar lección - Paso 13
Operadores lógicos — AND, OR, NOT
La mayoría de las decisiones reales combinan más de un dato. "¿El usuario inició sesión Y es un cliente de pago?" "¿El p…
Empezar lección - Paso 14
else if — decisiones con múltiples ramas
Un if/else binario basta cuando el mundo se divide limpiamente en dos casos. La mayoría de las veces no es así. Califica…
Empezar lección - Paso 15
Condiciones anidadas y ámbito de las variables
A veces la decisión interna depende de la externa. Solo preguntas "¿este usuario es un admin de pago?" después de haber …
Empezar lección - Paso 16
El operador ternario — condicionales en una línea
Todo if/else asigna un valor a algo. "Si x es positivo, asigna 'plus' a sign; si no, asigna 'minus' a sign." Escribir ci…
Empezar lección - Paso 17
La sentencia switch — casos discretos
Cuando comparas un valor con un puñado de constantes concretas (un string de estado, una opción de menú, un código HTTP,…
Empezar lección - Paso 18
Switch expressions — la forma más limpia de C# 8
La sentencia switch clásica hace una sola cosa: ramifica el código. C# 8 (.NET Core 3, 2019) introdujo la switch express…
Empezar lección - Paso 19
Métodos de string que guían decisiones
La mayoría de las condiciones en programas reales no son simples comparaciones de números: dependen de lo que escribió e…
Empezar lección - Paso 20
Capstone — la pequeña app de quiz
La app de quiz es el proyecto clásico para cerrar el tema de control de flujo: hacer tres preguntas, aceptar la respuest…
Empezar lección
intro a loops → for → while → do-while → break/continue → arrays → iterar (for/foreach) → multidimensional → jagged → simulador Rocket Launch
- Paso 21
Por qué existen los bucles — las cuatro variantes en C#
Los programas serían diminutos si cada valor tuviera su propia línea de código. La realidad es justo la contraria: los p…
Empezar lección - Paso 22
El bucle for — contar con intención
El bucle for es el caballo de batalla del código imperativo. Su encabezado de una sola línea concentra tres tareas: el i…
Empezar lección - Paso 23
Bucles while — iteración guiada por una condición
Un bucle while ejecuta su cuerpo mientras una condición sea verdadera. Su forma es la más simple de todos los bucles: wh…
Empezar lección - Paso 24
do-while — primero ejecuta, luego pregunta
while comprueba la condición antes de cada iteración. do-while la comprueba DESPUÉS. Esa única diferencia hace de do-whi…
Empezar lección - Paso 25
break y continue — vías de escape
La mayoría de los bucles terminan de forma natural — el contador llega al límite, la cola se vacía, la condición cambia.…
Empezar lección - Paso 26
Arrays — colecciones de tamaño fijo de un solo tipo
Hasta ahora, cada variable ha guardado un único valor. Los programas reales trabajan con colecciones: una lista de nombr…
Empezar lección - Paso 27
Recorrer un array — for, foreach y Length
Una vez que tienes un array, lo siguiente que haces con él es recorrer todos sus elementos. C# te ofrece dos formas natu…
Empezar lección - Paso 28
Arrays multidimensionales — cuadrículas en un solo bloque
Algunos datos son bidimensionales por naturaleza: un tablero de ajedrez, una hoja de cálculo, una imagen, un mapa de cal…
Empezar lección - Paso 29
Arrays escalonados — arrays de arrays
Un array multidimensional (lección anterior) es un rectángulo — todas las filas tienen la misma longitud. A veces los da…
Empezar lección - Paso 30
Capstone — el simulador de lanzamiento de cohetes
Es hora de combinar todo el capítulo. El simulador de lanzamiento de cohetes lee los parámetros de lanzamiento desde std…
Empezar lección
intro a métodos → void/return → parámetros → multi-params → overloading → defaults + named → ref/out/in → expression-bodied (=>) → recursión → simulador del clima
- Paso 31
Métodos — ponerle nombre a una tarea
Todos los programas que has escrito hasta ahora han sido un único bloque de top-level statements — leer la entrada, hace…
Empezar lección - Paso 32
Tipos de retorno — void frente a producir un valor
Todo método tiene un tipo de retorno. El tipo de retorno es el contrato que el método establece con quienes lo llaman: '…
Empezar lección - Paso 33
Parámetros — pasar datos a los métodos
Un parámetro es una variable que recibe su valor de quien llama cuando se invoca el método. En la firma del método, cada…
Empezar lección - Paso 34
Varios parámetros — el orden y los tipos importan
La mayoría de los métodos útiles reciben más de un parámetro. La firma los enumera en orden, separados por comas, cada u…
Empezar lección - Paso 35
Sobrecarga de métodos — mismo nombre, distintas firmas
A veces quieres que una misma operación conceptual funcione con entradas diferentes. Add(int, int) tiene sentido; tambié…
Empezar lección - Paso 36
Valores por defecto y argumentos con nombre
A veces un parámetro tiene un valor por defecto razonable que usa la mayoría de quienes llaman al método, y solo algunos…
Empezar lección - Paso 37
ref, out, in — paso explícito de parámetros
El paso por valor (el comportamiento por defecto) significa que el método recibe una copia. A veces realmente quieres qu…
Empezar lección - Paso 38
Miembros con cuerpo de expresión — el atajo =>
Muchos métodos son diminutos — una sentencia return, una expresión que evaluar. Escribir las llaves completas, el return…
Empezar lección - Paso 39
Recursión — métodos que se llaman a sí mismos
Un método recursivo es aquel que se llama a sí mismo. Suena a un bucle infinito a punto de ocurrir — y lo es, a menos qu…
Empezar lección - Paso 40
Capstone — el simulador del clima
Es hora de combinar todo el capítulo. El simulador del clima lee desde stdin un array de temperaturas de tamaño fijo e i…
Empezar lección
intro a clases → fields → constructores → propiedades (auto/full/computadas) → métodos de instancia → modificadores de acceso → readonly/const/init → miembros estáticos → encadenado de constructores → BankAccount
- Paso 41
Clases y objetos — el sustantivo de la POO
Hasta ahora, cada programa ha sido un script lleno de verbos: leer, calcular, imprimir. Los métodos (capítulo 4) nos die…
Empezar lección - Paso 42
Campos — el estado que lleva cada objeto
Toda clase interesante lleva DATOS: los valores que hacen que una instancia sea distinta de otra. Los datos declarados d…
Empezar lección - Paso 43
Constructores — cómo construir una instancia válida
Asignar a mano cada campo después de `new` es tedioso y propenso a errores: olvida uno y habrás entregado un objeto a me…
Empezar lección - Paso 44
Propiedades — campos con buenos modales
Los campos públicos mutables le dan vía libre al código que los usa: puede escribir cualquier valor en cualquier momento…
Empezar lección - Paso 45
Métodos en una clase — comportamiento ligado al estado
Los métodos dentro de una clase (el capítulo 4 cubrió la misma sintaxis para funciones locales sueltas) se convierten en…
Empezar lección - Paso 46
public, private, protected, internal — quién puede tocar qué
Cada miembro de una clase —campo, propiedad, método, constructor, tipo anidado— tiene un nivel de visibilidad. La visibi…
Empezar lección - Paso 47
readonly, const, init — cómo bloquear valores
A veces un valor debe poder asignarse UNA VEZ —al construir el objeto— y nunca más. Customer.Id, Order.PlacedAt, Point.X…
Empezar lección - Paso 48
static — estado y utilidades a nivel de clase
Todos los miembros que hemos visto hasta ahora pertenecían a una INSTANCIA: cada Cat tiene su propio Name; cada Account …
Empezar lección - Paso 49
Varios constructores — sobrecarga y encadenamiento
Igual que los métodos, los constructores se pueden sobrecargar: declararse varias veces con distintas listas de parámetr…
Empezar lección - Paso 50
Capstone — la clase BankAccount
Es hora de combinar todo el capítulo. La clase BankAccount reúne cada idea del capítulo 5 en un solo tipo: un Id readonl…
Empezar lección
intro a herencia (IS-A) → base/derivada + protected → virtual/override → keyword base → clases abstractas → cadenas de constructores : base(...) → sealed → interfaces → polimorfismo → Shape Zoo
- Paso 51
Herencia — construir sobre lo que ya tienes
Los dominios reales se solapan. Una SavingsAccount, una CheckingAccount y una CreditAccount comparten Balance, Deposit y…
Empezar lección - Paso 52
Base y derivada — qué se hereda
La herencia le da a una clase derivada acceso a los miembros PUBLIC y PROTECTED de su base. Los miembros privados de la …
Empezar lección - Paso 53
virtual y override — métodos polimórficos
Heredar un método tal cual es el caso sencillo. El caso interesante es REEMPLAZAR el comportamiento heredado: el Speak d…
Empezar lección - Paso 54
base — extender, no reemplazar
A veces un override no quiere REEMPLAZAR el comportamiento base, sino EXTENDERLO. Un SavingsAccount.Withdraw debería seg…
Empezar lección - Paso 55
Clases abstractas — bases que no puedes instanciar
A veces la clase base está INCOMPLETA a propósito. Un Animal no es un animal real: es una plantilla que dice 'todo anima…
Empezar lección - Paso 56
Herencia de constructores — : base(args)
Cuando creas una instancia de una clase derivada, se ejecutan TANTO el constructor base COMO el derivado. El de la base …
Empezar lección - Paso 57
sealed — cerrar la jerarquía
La herencia está abierta por defecto: cualquiera puede escribir `class MyDog : Dog { … }` y personalizar un método virtu…
Empezar lección - Paso 58
Interfaces — contratos sin implementación
Las clases abstractas describen tanto el contrato COMO el estado. A veces solo necesitas el contrato —'seas quien seas, …
Empezar lección - Paso 59
Polimorfismo — una forma, muchas implementaciones
POLIMORFISMO es el término general para el comportamiento hacia el que hemos ido avanzando a lo largo de este capítulo. …
Empezar lección - Paso 60
Capstone — el Shape Zoo
Es hora de combinar todo el capítulo. El Shape Zoo lee definiciones de figuras desde stdin, las reúne en un array polimó…
Empezar lección
intro a colecciones → List<T> básicos → Contains/Sort/Reverse → lambdas + predicados → LINQ Where/Any/Select → Dictionary<K,V> → ContainsKey/TryGetValue → HashSet<T> → tuplas + desestructuración → Inventory Tracker
- Paso 61
Colecciones — más allá de los arrays de tamaño fijo
Los arrays (Capítulo 3) son perfectos cuando conoces el tamaño de antemano. Los programas reales rara vez lo conocen. Un…
Empezar lección - Paso 62
List<T> — dinámica, ordenada e indexable
List<T> es la colección más usada en C#. Es un envoltorio sobre un array que crece a medida que le agregas elementos. Ag…
Empezar lección - Paso 63
Operaciones de List — Contains, IndexOf, Sort, Reverse
List<T> trae un pequeño conjunto de MÉTODOS MIEMBRO que cubren las operaciones comunes más allá de agregar/quitar/indexa…
Empezar lección - Paso 64
Lambdas y predicados — código como datos
Hasta ahora, los métodos han tenido NOMBRE: los declaramos con int Add(int a, int b) y los llamamos por su nombre. Mucho…
Empezar lección - Paso 65
Fundamentos de LINQ — Where, Any, Select, Count
LINQ (Language-Integrated Query) es un conjunto de métodos de extensión sobre `IEnumerable<T>` que te permiten filtrar, …
Empezar lección - Paso 66
Dictionary<K, V> — búsqueda por clave
List<T> es ideal cuando buscas cosas por POSICIÓN. Cuando las buscas por CLAVE (un nombre de usuario, un id de pedido, u…
Empezar lección - Paso 67
ContainsKey, TryGetValue, Remove — código defensivo con diccionarios
Leer una clave inexistente de un Dictionary lanza KeyNotFoundException: un fallo en tiempo de ejecución. El código defen…
Empezar lección - Paso 68
HashSet<T> — elementos únicos, Contains rápido
Cuando solo te importa SI algo está en una colección (no su posición, ni cuántas veces aparece, ni datos asociados), Has…
Empezar lección - Paso 69
Tuplas — devolver varios valores de forma limpia
Los métodos que necesitan devolver más de un valor tienen tres opciones. Parámetros out (Capítulo 4): funciona, pero se …
Empezar lección - Paso 70
Capstone — el Inventory Tracker
Es hora de combinar todo el capítulo. El Inventory Tracker lee comandos desde stdin y opera sobre un pequeño almacén de …
Empezar lección
intro a excepciones → try/catch → múltiples catch + filtros → finally → throw + rethrow → tipos built-in → excepciones personalizadas → mejores prácticas → using + IDisposable → Resource Pool
- Paso 71
Excepciones — cuando algo falla en tiempo de ejecución
El compilador demuestra que tus tipos encajan y que tu sintaxis es válida. No puede demostrar que tu archivo exista, que…
Empezar lección - Paso 72
try / catch — manejar los fallos con elegancia
Un bloque `try` envuelve código que podría lanzar una excepción. Si algo dentro la lanza, la ejecución omite el resto de…
Empezar lección - Paso 73
Varios catch — maneja cada fallo a su manera
Un solo try puede tener MUCHOS bloques catch, cada uno para un tipo de excepción distinto. Se ejecuta el primero cuyo ti…
Empezar lección - Paso 74
finally — código que siempre se ejecuta
A veces necesitas que un código se ejecute PASE LO QUE PASE: tanto si el try tuvo éxito como si se capturó una excepción…
Empezar lección - Paso 75
Lanzar excepciones — señalar un fallo a propósito
Hasta ahora hemos estado CAPTURANDO excepciones lanzadas por el framework. A menudo necesitas LANZAR las tuyas: cuando n…
Empezar lección - Paso 76
Los tipos de excepción integrados más comunes
La biblioteca estándar de .NET define cientos de tipos de excepción, pero un pequeño conjunto cubre el 90% de los casos …
Empezar lección - Paso 77
Tipos de excepción personalizados — hablar el idioma de tu dominio
Los tipos de excepción integrados cubren problemas genéricos. Para fallos ESPECÍFICOS DEL DOMINIO, definir tu propio tip…
Empezar lección - Paso 78
Buenas prácticas con excepciones — cuándo NO capturar
Lanzar es fácil; capturar bien es difícil. El error más común en el manejo de excepciones es CAPTURAR DE MÁS: envolver c…
Empezar lección - Paso 79
using + IDisposable — limpieza garantizada
Archivos, conexiones de red, handles de bases de datos, locks: son RECURSOS que el sistema operativo te entrega y espera…
Empezar lección - Paso 80
Capstone — el Resource Pool
Es hora de combinar todo el capítulo. El capstone Resource Pool simula un pequeño sistema de préstamo y devolución: los …
Empezar lección
intro a generics → clase genérica Box<T> → métodos genéricos + inferencia → multi-parámetros → constraints (where) → interfaces genéricas → IEnumerable/ICollection/IList → Action/Func/Predicate → default(T) + varianza → Typed Bag
- Paso 81
Genéricos — escribe una vez, verifica tipos en todas partes
Llevas USANDO genéricos desde el capítulo 7 — `List<T>`, `Dictionary<K, V>`, `HashSet<T>`. Ahora vamos a mirar detrás de…
Empezar lección - Paso 82
Clases genéricas — Box<T>
Una clase genérica declara uno o más parámetros de tipo entre corchetes angulares después del nombre de la clase: `class…
Empezar lección - Paso 83
Métodos genéricos — parámetros de tipo en el método
Las CLASES genéricas atan el parámetro de tipo a las instancias: todos los métodos de un Box<int> usan int. Los MÉTODOS …
Empezar lección - Paso 84
Varios parámetros de tipo — KeyValue<K, V>
Hasta ahora, cada ejemplo ha tenido UN solo parámetro de tipo. Los tipos reales a menudo necesitan MÁS: `Dictionary<K, V…
Empezar lección - Paso 85
Restricciones genéricas — acotar lo que puede ser T
Dentro de una clase o un método genérico, el compilador no sabe nada de T más allá de 'es algún tipo'. Solo puedes llama…
Empezar lección - Paso 86
Interfaces genéricas — contratos parametrizados por tipo
Las interfaces siguen las mismas reglas de genéricos que las clases. `interface IRepository<T> { T Get(int id); void Sav…
Empezar lección - Paso 87
Las interfaces genéricas de colección — IEnumerable, ICollection, IList
La jerarquía de colecciones de .NET se construye a partir de un pequeño conjunto de interfaces genéricas. Conocerlas te …
Empezar lección - Paso 88
Action, Func, Predicate — los tipos de delegado estándar
Un DELEGADO es una referencia tipada a un método: 'una variable que contiene una función'. Antes de los genéricos, defin…
Empezar lección - Paso 89
default(T), nulabilidad y un vistazo a la varianza
Dos piezas más de la caja de herramientas de los genéricos. La palabra clave DEFAULT te da el 'valor cero' natural del t…
Empezar lección - Paso 90
Capstone — el Typed Bag
Es hora de combinar todo el capítulo. El capstone Typed Bag implementa un `Bag<T> where T : IComparable<T>` genérico que…
Empezar lección
intro a delegates → instancias + lambdas → multicast +=/-= + invocation list → delegates como parámetros → keyword event + pub/sub → EventHandler<T> + EventArgs custom → fire seguro (?.Invoke + copia thread) → event vs campo delegate → patrón observer → Stock Monitor
- Paso 91
Delegados — métodos como valores
El capítulo 9 presentó Action, Func y Predicate: tres familias de referencias tipadas a funciones. Por debajo, todas son…
Empezar lección - Paso 92
Guardar e invocar instancias de delegados
Una vez que tienes un tipo de delegado, creas INSTANCIAS asignando métodos a variables de delegado. Las tres formas sint…
Empezar lección - Paso 93
Delegados multicast — += y la lista de invocación
Una variable de delegado puede apuntar a MÁS de un método a la vez. Al invocarla, se ejecutan TODOS los métodos asignado…
Empezar lección - Paso 94
Delegados como parámetros — cómo construir helpers de orden superior
Los métodos que reciben otros métodos como parámetros son métodos de ORDEN SUPERIOR. Te permiten parametrizar el COMPORT…
Empezar lección - Paso 95
Eventos — el patrón publicador-suscriptor
Los delegados multicast te permiten difundir: una sola invocación ejecuta todos los métodos registrados. Pero hay un pro…
Empezar lección - Paso 96
EventHandler<T> y EventArgs — la forma estándar de un evento
La mayoría de los eventos necesitan comunicar QUÉ pasó, no solo 'pasó algo'. Un evento de clic lleva la posición del cli…
Empezar lección - Paso 97
Disparar eventos de forma segura — comprobar null, copiar, despachar
Disparar un evento parece sencillo: `MyEvent.Invoke(this, args)`. Pero hay tres minas sutiles: el evento puede ser null …
Empezar lección - Paso 98
Eventos vs. delegados — cuándo usar cada uno
Los eventos y los campos de tipo delegado se ven casi idénticos. Ambos difunden a varios suscriptores mediante +=/-=. Am…
Empezar lección - Paso 99
El patrón Observer en C# — los eventos como primitiva del lenguaje
OBSERVER es uno de los patrones de diseño originales del Gang of Four: una forma de conectar objetos 'sujeto' y 'observa…
Empezar lección - Paso 100
Capstone — el Stock Price Monitor
Es hora de combinar todo el capítulo. El capstone Stock Price Monitor implementa un publicador (`Stock`) y DOS suscripto…
Empezar lección
intro a regex → literales + anclas (^, $, \b) → clases de caracteres (\d \w \s + corchetes) → cuantificadores (* + ? {n,m} + lazy) → grupos + alternación → grupos nombrados + backreferences → clase Regex (IsMatch/Match/Matches + opciones) → Replace/Split + MatchEvaluator → lookarounds (?=, ?!, ?<=, ?<!) → Log Parser
- Paso 101
Expresiones regulares — patrones para texto
Una expresión regular (REGEX, para abreviar) es un pequeño lenguaje para describir PATRONES en texto. 'Un número de telé…
Empezar lección - Paso 102
Literales, anclas y caracteres especiales
La mayoría de los caracteres de una regex coinciden CONSIGO MISMOS: `a` coincide con la letra a, `5` coincide con el díg…
Empezar lección - Paso 103
Clases de caracteres — dígito, palabra, espacio en blanco y corchetes
Una CLASE DE CARACTERES es un conjunto de caracteres; la regex coincide con UN carácter CUALQUIERA del conjunto. `[abc]`…
Empezar lección - Paso 104
Cuantificadores — *, +, ?, {n,m}
Un CUANTIFICADOR se aplica al elemento anterior (un literal, una clase de caracteres o un grupo) e indica cuántas veces …
Empezar lección - Paso 105
Grupos y alternancia — (…) y |
Los paréntesis cumplen dos funciones en una regex. AGRUPAR: te permiten cuantificar una secuencia (`(abc)+`) o aplicar a…
Empezar lección - Paso 106
Grupos con nombre y referencias inversas
Los grupos numerados funcionan, pero son FRÁGILES: añade un paréntesis en medio del patrón y todos los índices posterior…
Empezar lección - Paso 107
La clase Regex — IsMatch, Match, Matches y opciones
La API de regex de .NET está en `System.Text.RegularExpressions`. El tipo principal es `Regex`: es a la vez una clase qu…
Empezar lección - Paso 108
Replace y Split — transformaciones de texto
`Regex.Replace(input, pattern, replacement)` devuelve un string NUEVO con cada coincidencia reemplazada. `Regex.Replace(…
Empezar lección - Paso 109
Lookarounds — aserciones que no consumen
A veces quieres encontrar un patrón que va seguido (o precedido) de algo concreto, SIN incluir ese contexto en la coinci…
Empezar lección - Paso 110
Capstone — el Log Parser
Es hora de combinar todo el capítulo. El capstone Log Parser lee líneas de log estructuradas desde stdin y extrae campos…
Empezar lección
intro a async → Task + Task<T> → keywords async/await → continuations + máquina de estados → Task.WhenAll / WhenAny → excepciones async → CancellationToken → Task.FromResult + CompletedTask → pitfalls (async void, deadlocks) → Download Aggregator
- Paso 111
Async — por qué tu código deja de quedarse esperando
Todos los programas que has escrito hasta ahora han sido SÍNCRONOS: cada línea espera a que termine la anterior antes de…
Empezar lección - Paso 112
Task y Task<T> — la unidad de trabajo async
Un `Task` representa una operación asíncrona: algo que terminará en algún momento (o fallará, o será cancelado). `Task` …
Empezar lección - Paso 113
async y await — la sintaxis que lo hace legible
Los Task existen desde .NET 4 (2010). Lo que hizo POPULAR a async fueron las palabras clave ASYNC/AWAIT, añadidas en C# …
Empezar lección - Paso 114
Continuaciones — lo que realmente hace el compilador
Cuando escribes `await something`, el compilador en realidad no pausa la ejecución a mitad del método. Divide el método …
Empezar lección - Paso 115
WhenAll y WhenAny — ejecutar tareas en paralelo
Hacer await de las tareas una por una las ejecuta en SECUENCIA: esperas a la primera y luego arrancas la segunda. Con 10…
Empezar lección - Paso 116
Excepciones en async — try/catch y AggregateException
Las excepciones async se ven casi idénticas a las síncronas — ese es justamente el objetivo de async/await. Cuando falla…
Empezar lección - Paso 117
Cancelación — permitir que quien llama detenga tareas de larga duración
Las operaciones async pueden tardar un buen rato. A veces quien las llama decide que ya no deben seguir: el usuario hizo…
Empezar lección - Paso 118
Task.CompletedTask, Task.FromResult — tareas ya completadas
A veces un método async no tiene ningún trabajo asíncrono que hacer. Implementa una interfaz `IXxxAsync` por consistenci…
Empezar lección - Paso 119
Trampas de async — async void, deadlocks, sync-over-async
El código async tiene su propio conjunto de PELIGROS que no existen en el código síncrono. La mayoría de los bugs async …
Empezar lección - Paso 120
Capstone — el Download Aggregator
Es hora de combinar todo el capítulo. El capstone Download Aggregator simula un fan-out concurrente: 'descarga' varios r…
Empezar lección
tipos por valor vs referencia → definir un struct → struct vs class (trampa del struct mutable) → enums → enums [Flags] → structs readonly/inmutables → records (igualdad por valor) → expresiones with + desestructuración → matriz de decisión record/class/struct → capstone Vector2D
- Paso 121
Tipos por valor vs tipos por referencia — la gran división
Todo tipo en C# cae a un lado de una línea que define cómo se comporta tu programa: o es un tipo por valor o es un tipo …
Empezar lección - Paso 122
Definir un struct
Un struct es la forma de definir tu propio tipo por valor. Sintácticamente se ve casi idéntico a una clase: puede tener …
Empezar lección - Paso 123
struct vs class — cómo elegir, y la trampa del struct mutable
Ahora que sabes definir ambos, la pregunta práctica es: ¿qué debería ser un tipo determinado? La respuesta por defecto e…
Empezar lección - Paso 124
Enums — nombres para un conjunto fijo de valores
Un enum (enumeración) es un tipo por valor que da nombres amigables a un conjunto fijo de constantes relacionadas. En lu…
Empezar lección - Paso 125
Enums [Flags] — combinar opciones con bits
A veces un valor no es una única opción de un conjunto, sino una COMBINACIÓN de opciones independientes: un archivo pued…
Empezar lección - Paso 126
Structs readonly e inmutabilidad por diseño
Hemos usado la palabra 'inmutable' una y otra vez; ahora vamos a precisarla y darle fuerza con las características del l…
Empezar lección - Paso 127
Records — igualdad por valor con una sola palabra clave
C# 9 introdujo el `record`, un tipo por referencia creado específicamente para datos inmutables con igualdad basada en v…
Empezar lección - Paso 128
Expresiones with y deconstrucción
Los records son inmutables, así que no puedes cambiar una propiedad después de construirlos. Pero muy a menudo quieres u…
Empezar lección - Paso 129
record, class, struct y record struct — la matriz de decisión
Ahora tienes cuatro formas de declarar un tipo, y elegir entre ellas es una de las decisiones de diseño más comunes en C…
Empezar lección - Paso 130
Capstone — el tipo por valor de vector 2D
Es hora de combinar el capítulo en un único y elegante tipo por valor. El capstone Geometry construye un `Vector2D` como…
Empezar lección
DateTime (ticks + Kind) → Now/Today/UtcNow + constructores → componentes (DayOfWeek/DayOfYear) → TimeSpan (componente vs Total) → aritmética (Add*, fecha − fecha) → formato (InvariantCulture) → parseo (Parse/TryParse/ParseExact) → comparación y ordenamiento → DateTimeOffset y UTC → Planificador de Eventos
- Paso 131
Qué es realmente un DateTime — ticks y Kind
Casi todo programa tarde o temprano tiene que razonar sobre *cuándo* ocurrió algo: cuándo se hizo un pedido, cuándo expi…
Empezar lección - Paso 132
Crear fechas — Now, Today, UtcNow y constructores
Hay dos grandes formas de obtener un DateTime: pedirle al reloj del sistema el momento presente, o construir explícitame…
Empezar lección - Paso 133
Leer las partes — Year, Month, DayOfWeek, DayOfYear
Una vez que tienes un DateTime, a menudo querrás extraer de él campos individuales: el año para el encabezado de un info…
Empezar lección - Paso 134
TimeSpan — medir duraciones
Un DateTime responde "¿cuándo?"; un TimeSpan responde "¿cuánto tiempo?". Mientras que DateTime es un punto absoluto en l…
Empezar lección - Paso 135
Aritmética de fechas — sumar intervalos y restar fechas
Ahora que tienes tanto un punto absoluto (DateTime) como una duración (TimeSpan), puedes hacer las dos operaciones que v…
Empezar lección - Paso 136
Formatear fechas — estándar y personalizados, siempre con InvariantCulture
Convertir un DateTime en texto es algo que hace todo programa — para logs, nombres de archivo, payloads de API y pantall…
Empezar lección - Paso 137
Parsear fechas — Parse, TryParse y ParseExact
Parsear es la imagen especular de formatear: convertir texto de vuelta en un DateTime. También es donde se esconden los …
Empezar lección - Paso 138
Comparar y ordenar fechas
Como un DateTime es, en esencia, un único conteo de ticks, comparar dos de ellos es tan natural como comparar dos número…
Empezar lección - Paso 139
DateTimeOffset y por qué guardar en UTC
El DateTime a secas tiene una debilidad silenciosa: un valor con Kind == Unspecified no indica a qué zona horaria perten…
Empezar lección - Paso 140
Capstone: construye un planificador de eventos
Es hora de poner en práctica todo el capítulo. Un planificador es la aplicación de fecha y hora por excelencia: parsea m…
Empezar lección
StringBuilder (append/insert, sin copias) → cirugía de strings Split/Join/Substring/Pad → StringReader/StringWriter (TextReader/TextWriter) → serializar JSON (System.Text.Json) → Deserialize<T> + sin distinguir mayúsculas → JsonSerializerOptions (camelCase, indentado, omitir nulls) → DOM con JsonDocument/JsonElement → parsear y construir CSV a mano → MemoryStream + codificación UTF-8 (bytes↔texto) → capstone procesador de config y órdenes JSON
- Paso 151
StringBuilder — construir texto sin desperdicio
Ya sabes que string es inmutable: una vez que un string existe en el heap, sus caracteres no pueden cambiar nunca. Toda …
Empezar lección - Paso 152
Cirugía de strings — Split, Join, Substring y compañía
La mayor parte del procesamiento de texto del mundo real se reduce a un pequeño vocabulario de métodos de string aplicad…
Empezar lección - Paso 153
TextReader y TextWriter — StringReader y StringWriter
C# modela toda la entrada de texto detrás de una única clase abstracta, TextReader, y toda la salida de texto detrás de …
Empezar lección - Paso 154
JSON, parte 1 — serializar con System.Text.Json
JSON — JavaScript Object Notation — es la lingua franca del intercambio de datos moderno. Las APIs lo devuelven, los arc…
Empezar lección - Paso 155
JSON, parte 2 — deserializar en objetos tipados
La deserialización es el viaje de vuelta: entra texto JSON y sale un objeto de C#. El método es JsonSerializer.Deseriali…
Empezar lección - Paso 156
JSON, parte 3 — dar forma a la salida con JsonSerializerOptions
JsonSerializerOptions es el panel de control para ambas direcciones de JSON. Ya conociste PropertyNameCaseInsensitive pa…
Empezar lección - Paso 157
JSON, parte 4 — el DOM con JsonDocument y JsonElement
A veces no tienes — o no quieres — un tipo de C# en el que deserializar. Quizá la forma es dinámica, solo necesitas un c…
Empezar lección - Paso 158
CSV — parsear y construir datos delimitados a mano
CSV — valores separados por comas (comma-separated values) — es el formato de datos más antiguo y testarudo de la inform…
Empezar lección - Paso 159
Streams y codificación — bytes, texto y MemoryStream
Debajo de todo reader y writer de texto hay un Stream — la abstracción para una secuencia de BYTES, no de caracteres. Lo…
Empezar lección - Paso 160
Capstone — procesador de configuración JSON y pedidos
Es hora de poner a trabajar todo el capítulo. Vas a construir un procesador de datos pequeño pero realista: lee de la en…
Empezar lección
Consulta, proyecta, agrupa, une y agrega cualquier colección — y domina la ejecución diferida.
- Paso 141
LINQ a fondo — sintaxis de query vs. sintaxis de métodos
Ya conociste LINQ de pasada en el capítulo 7, donde Where y Any te ayudaron a filtrar una lista. Este capítulo va a fond…
Empezar lección - Paso 142
Filtrar con Where
Where es el caballo de batalla de LINQ. Recibe un predicado — una función que devuelve un bool — y produce solo los elem…
Empezar lección - Paso 143
Proyectar con Select, tipos anónimos y SelectMany
Where decide qué elementos sobreviven; Select decide en qué se convierte cada elemento superviviente. Esta operación se …
Empezar lección - Paso 144
Ordenar con OrderBy, OrderByDescending y ThenBy
OrderBy ordena una secuencia según una clave que extraes de cada elemento. `people.OrderBy(p => p.Age)` ordena a las per…
Empezar lección - Paso 145
Agrupar con GroupBy e IGrouping
GroupBy divide una secuencia en grupos que comparten una clave común. `words.GroupBy(w => w[0])` agrupa las palabras por…
Empezar lección - Paso 146
Agregar con Count, Sum, Min, Max, Average y Aggregate
Los operadores de agregación reducen toda una secuencia a un único valor. Los cinco de todos los días son Count, Sum, Mi…
Empezar lección - Paso 147
Combinar secuencias con Join y GroupJoin
Los datos reales rara vez están en una sola lista. Tienes los clientes en una colección y sus pedidos en otra, vinculado…
Empezar lección - Paso 148
Operaciones de conjuntos y particionado
LINQ incluye las operaciones clásicas de conjuntos como operadores que comparan dos secuencias. Distinct() elimina los d…
Empezar lección - Paso 149
Ejecución diferida vs. inmediata
Esta es la idea más importante de LINQ — y la que confunde a casi todo el mundo al principio. La mayoría de los operador…
Empezar lección - Paso 150
Capstone — el motor de informes de ventas
Es hora de poner en práctica todo el capítulo. Un informe de ventas es la tarea LINQ por excelencia: tomar filas de tran…
Empezar lección
Ejecuta codigo en paralelo sin corromper tus datos: hilos, locks, Interlocked, Tasks, bucles Parallel, colecciones concurrentes, primitivas de coordinacion y tuberias productor/consumidor.
- Paso 171
Hilos — ejecutar código en paralelo
Hasta ahora, cada programa que escribiste se ejecutaba en un único hilo de ejecución: una instrucción tras otra, de arri…
Empezar lección - Paso 172
Condiciones de carrera — cuando los hilos chocan
En el momento en que dos hilos escriben en la MISMA variable sin coordinación, tienes una condición de carrera: un error…
Empezar lección - Paso 173
lock y Monitor — exclusión mutua
La sentencia lock es la herramienta cotidiana de C# para la exclusión mutua. Escribes lock (someObject) { ... } y el run…
Empezar lección - Paso 174
Interlocked — operaciones atómicas sin lock (lock-free)
Los locks son de uso general, pero para el caso más común — actualizar de forma atómica un único número — son más pesado…
Empezar lección - Paso 175
Task.Run — trabajo de CPU sin hilos en bruto
Crear un Thread en bruto es una operación bastante pesada: cada uno consume alrededor de un megabyte de stack y tarda un…
Empezar lección - Paso 176
Parallel.For y Parallel.ForEach
A menudo, el trabajo que quieres paralelizar es simplemente un bucle: hacer la misma operación independiente con cada el…
Empezar lección - Paso 177
Colecciones concurrentes — contenedores thread-safe
Las colecciones ordinarias — List<T>, Dictionary<K,V>, Queue<T> — NO son thread-safe (seguras para hilos). Si dos hilos …
Empezar lección - Paso 178
Coordinación — CountdownEvent, Barrier y reset events
Hasta ahora hemos protegido DATOS compartidos. La otra mitad de la concurrencia es coordinar los TIEMPOS — hacer que un …
Empezar lección - Paso 179
Productor/consumidor con BlockingCollection
El patrón productor/consumidor es una de las estructuras más útiles de la programación concurrente: uno o más hilos PROD…
Empezar lección - Paso 180
Capstone — el agregador de palabras en paralelo
Este capstone fusiona todo el capítulo en un pequeño motor de procesamiento de datos: un AGREGADOR PARALELO. Lee un fluj…
Empezar lección
Tipos de referencia anulables, los operadores de null y todo el arsenal de coincidencia de patrones — de tipo, de propiedad, relacionales, lógicos, de tupla, de lista y posicionales — culminando en un intérprete de comandos basado en patrones.
- Paso 161
Tipos de referencia nullable — null como una cuestión de primera clase
Durante la mayor parte de la vida de C#, cualquier tipo por referencia podía ser null sin que nadie se diera cuenta, y e…
Empezar lección - Paso 162
Operadores de null — ?. ?[] ?? y ??=
Una vez que aceptas que algunos valores pueden ser null, necesitas herramientas ergonómicas para trabajar con ellos — no…
Empezar lección - Paso 163
Pattern matching — el operador is se hace mayor
Ya conoces el operador `is` como una prueba de tipo de sí o no: `obj is string` devuelve true cuando `obj` es un string.…
Empezar lección - Paso 164
Switch expressions — patrones como ramas
La SENTENCIA `switch` que conociste antes ramifica y va pasando de un caso a otro. La EXPRESIÓN `switch`, añadida en C# …
Empezar lección - Paso 165
Patrones de propiedades — comparar con la forma de un objeto
Hasta ahora, nuestros patrones han inspeccionado el TIPO de un valor o su identidad. Los patrones de propiedades (proper…
Empezar lección - Paso 166
Patrones relacionales y lógicos — rangos y combinadores
C# 9 añadió dos familias de patrones que convierten el pattern matching en una forma concisa de describir RANGOS y COMBI…
Empezar lección - Paso 167
Patrones de tupla — switch sobre varios valores a la vez
A veces una decisión depende de DOS valores juntos, no de uno. El resultado de piedra, papel o tijera depende de (la tuy…
Empezar lección - Paso 168
Patrones de lista — reconocer la forma de una secuencia
C# 11 (lanzado con .NET 7 y totalmente compatible con nuestro runner de .NET 8) añadió los patrones de lista (list patte…
Empezar lección - Paso 169
Patrones posicionales — deconstruir records en un match
Los records y el pattern matching se diseñaron el uno para el otro. Un record posicional como `record Point(int X, int Y…
Empezar lección - Paso 170
Capstone — un intérprete de comandos con pattern matching
Este capstone teje todos los hilos del capítulo en un pequeño intérprete. Vas a leer un flujo de comandos, parsear cada …
Empezar lección
Construye un arnés de aserciones a mano, aprende Arrange-Act-Assert y el ciclo rojo-verde-refactor, prueba casos límite y excepciones, aísla unidades con dobles de prueba, y termina aplicando TDD a un conversor de números romanos tras un mini runner de pruebas que totaliza los resultados.
- Paso 191
¿Por qué probar? Lo que te aportan las pruebas automatizadas
Cada programa que has escrito hasta ahora en este curso lo has probado tú: leyendo la salida esperada, ejecutándolo y re…
Empezar lección - Paso 192
Tu primera prueba — un pequeño arnés Check.Equal
Escribir `expected == actual ? "PASS" : "FAIL"` a mano cada vez es repetitivo, y la repetición es justo por donde se cue…
Empezar lección - Paso 193
Arrange, Act, Assert — la forma de una buena prueba
Toda prueba clara tiene el mismo ritmo de tres tiempos: PREPARAS (Arrange) las entradas y los objetos que necesitas, ACT…
Empezar lección - Paso 194
Rojo, Verde, Refactorizar — el ciclo de TDD
El desarrollo guiado por pruebas (Test-Driven Development) invierte el orden habitual: escribes primero la PRUEBA, ves c…
Empezar lección - Paso 195
Probar casos límite — piensa como un adversario
La mayoría de los bugs no se esconden en medio del rango de entrada: acechan en los BORDES. El 'camino feliz' (una lista…
Empezar lección - Paso 196
Probar excepciones — afirmar que un método lanza una excepción
El contrato de un método no es solo lo que DEVUELVE para una entrada válida: también es lo que LANZA para una entrada in…
Empezar lección - Paso 197
Dobles de prueba — fakes y stubs mediante interfaces
Una prueba unitaria aísla UNA unidad. Pero las unidades reales tienen colaboradores: un servicio de facturación que nece…
Empezar lección - Paso 198
Pruebas parametrizadas — una aserción, una tabla de casos
Cuando quieres probar el MISMO comportamiento con MUCHAS entradas, copiar y pegar una línea de aserción diez veces es un…
Empezar lección - Paso 199
Organización de pruebas — nombres, foco, independencia
Una suite de pruebas es código y, como todo código, puede estar limpia o ser un desastre. Tres hábitos separan las suite…
Empezar lección - Paso 200
Capstone — un mini ejecutor de pruebas para un conversor de números romanos
Este capstone une todo el capítulo: vas a desarrollar con TDD una pequeña funcionalidad detrás de un ejecutor de pruebas…
Empezar lección
Refactoriza codigo con malos olores hacia disenos limpios y flexibles: clausulas de guarda, Extraer Metodo y los cinco principios SOLID, preservando el comportamiento.
- Paso 181
Qué es el código limpio — y por qué la legibilidad le gana al ingenio
Llevas dieciocho capítulos aprendiendo lo que C# puede hacer. Este capítulo trata de algo distinto: cómo escribir código…
Empezar lección - Paso 182
Cláusulas de guarda — aplana la pirámide de if con retornos tempranos
Las sentencias if anidadas son una de las fuentes más comunes de código ilegible. Cuando cada paso de un método está env…
Empezar lección - Paso 183
Extract Method — descompón un método largo en métodos pequeños con nombre
Extract Method (extraer método) es la refactorización más útil que existe, en cualquier lenguaje. Cuando un método hace …
Empezar lección - Paso 184
Responsabilidad única — un solo motivo para cambiar
La S de SOLID es el Principio de Responsabilidad Única (Single Responsibility Principle, SRP): una clase o un método deb…
Empezar lección - Paso 185
Abierto/Cerrado — extiende con polimorfismo, no edites un switch
La O de SOLID es el Principio Abierto/Cerrado (Open/Closed Principle, OCP): las entidades de software deberían estar abi…
Empezar lección - Paso 186
Sustitución de Liskov — los subtipos deben respetar el contrato base
La L de SOLID es el Principio de Sustitución de Liskov (Liskov Substitution Principle, LSP), llamado así por Barbara Lis…
Empezar lección - Paso 187
Segregación de interfaces — muchas interfaces pequeñas mejor que una gorda
La I de SOLID es el Principio de Segregación de Interfaces (Interface Segregation Principle, ISP): ningún cliente deberí…
Empezar lección - Paso 188
Inversión de dependencias — depende de abstracciones, no de concreciones
La D de SOLID es el Principio de Inversión de Dependencias (Dependency Inversion Principle, DIP): los módulos de alto ni…
Empezar lección - Paso 189
Inyección de dependencias — inyección por constructor a mano
La inversión de dependencias te dijo que dependieras de abstracciones; la inyección de dependencias (Dependency Injectio…
Empezar lección - Paso 190
Capstone — refactoriza un god-method con mal olor en código limpio y SOLID
Este capstone reúne todo el capítulo. Recibes un único god-method — una maraña de ifs anidados, un switch sobre el tipo,…
Empezar lección
Mide como escala tu codigo: tasas de crecimiento Big-O, busqueda y ordenamiento, recursion y memoizacion, compromisos entre estructuras de datos, y tiempo contra espacio — culminando en un taller de two-sum que compara O(n^2) ingenuo con O(n) optimo.
- Paso 201
Big-O — medir cómo escala el código
Hasta ahora hemos juzgado el código sobre todo por si produce la respuesta correcta. Este capítulo agrega una segunda pr…
Empezar lección - Paso 202
O(1) vs O(n) — índice frente a recorrido
Las dos complejidades más comunes que escribirás son O(1), tiempo constante, y O(n), tiempo lineal. Tiempo constante sig…
Empezar lección - Paso 203
O(log n) y O(n log n) — dividir a la mitad y los buenos ordenamientos
El tiempo logarítmico, O(log n), es lo que obtienes cuando cada paso descarta una FRACCIÓN constante del trabajo restant…
Empezar lección - Paso 204
O(n^2) y más allá — detectar los lentos
El tiempo cuadrático, O(n²), es la primera complejidad que duele de verdad a escala, y es la más fácil de escribir por a…
Empezar lección - Paso 205
Búsqueda — lineal frente a binaria
Buscar (averiguar si un valor está en una colección y dónde) es el algoritmo que escribirás con más frecuencia, así que …
Empezar lección - Paso 206
Fundamentos de ordenamiento — ordenamientos didácticos vs el Array.Sort real
Ordenar consiste en colocar los elementos en orden, y vale la pena implementar a mano un ordenamiento sencillo una vez; …
Empezar lección - Paso 207
Complejidad de la recursión — recurrencias y memoización
La recursión puede esconder su verdadero costo detrás de un código elegante, así que analizar la complejidad recursiva e…
Empezar lección - Paso 208
Compromisos entre estructuras de datos — elegir el contenedor adecuado
Elegir la estructura de datos adecuada suele dar una mejora de velocidad mayor que cualquier algoritmo ingenioso, porque…
Empezar lección - Paso 209
Complejidad espacial — cambiar memoria por tiempo
Big-O mide algo más que el tiempo; también mide la MEMORIA. La complejidad espacial cuenta cuánta memoria EXTRA necesita…
Empezar lección - Paso 210
Capstone — two-sum, ingenuo vs óptimo
Este capstone une todo el capítulo en un único problema famoso: TWO-SUM. Dada una lista de enteros y un objetivo, decide…
Empezar lección
Stack vs heap, el GC generacional, IDisposable, boxing, Span<T>, stackalloc, asignaciones de strings y cómo medir para escribir código con pocas asignaciones.
- Paso 211
Stack vs heap — dónde viven realmente tus valores
Todo programa C# en ejecución gestiona la memoria en dos lugares muy distintos, y entender cuál es cuál explica la mayor…
Empezar lección - Paso 212
El recolector de basura — generaciones y qué se recolecta
C# es un lenguaje *administrado* (managed), y el corazón de esa palabra es la gestión automática de la memoria: asignas …
Empezar lección - Paso 213
IDisposable y using — limpieza determinista
El recolector de basura es brillante recuperando *memoria*, pero la memoria no es el único recurso que retiene un progra…
Empezar lección - Paso 214
Boxing y unboxing — la asignación oculta en el heap
Aquí va un hecho que sorprende a mucha gente: en C#, *todo* es compatible con `object`, incluido un `int`. `object o = 4…
Empezar lección - Paso 215
Span<T> y ReadOnlySpan<T> — slicing sin asignar memoria
Supón que tienes un array de mil enteros y quieres trabajar solo con los cien del medio. Lo obvio es copiarlos a un nuev…
Empezar lección - Paso 216
stackalloc — buffers temporales con costo cero en el heap
A veces necesitas un pequeño array temporal — un buffer de trabajo para construir un resultado, guardar valores intermed…
Empezar lección - Paso 217
Asignaciones de strings — interning, StringBuilder y slicing con spans
Los strings son el tipo que más asignaciones de memoria genera en la mayoría de los programas, por una razón fundamental…
Empezar lección - Paso 218
Struct vs class — el ángulo de la presión de asignación
El capítulo 13 presentó `struct` y `class` como una cuestión de *semántica*: los tipos por valor se copian, los tipos po…
Empezar lección - Paso 219
Medir y evitar asignaciones
La regla de oro del trabajo de rendimiento es: *mide, no adivines*. La intuición sobre qué es lento es notoriamente poco…
Empezar lección - Paso 220
Capstone — el analizador de lecturas con presupuesto de asignaciones
Este capstone reúne todo el capítulo en una sola rutina. Te entregan una línea de lecturas de sensores y te piden tres e…
Empezar lección
Inspecciona tipos en tiempo de ejecución, construye e invoca miembros dinámicamente, diseña atributos personalizados y crea motores guiados por atributos — y aceléralos con caché.
- Paso 221
Reflexión — un programa que se inspecciona a sí mismo
Hasta ahora tu código siempre ha sabido, en el momento en que lo escribiste, exactamente con qué tipos trabajaba. Escrib…
Empezar lección - Paso 222
Inspeccionar miembros — propiedades, métodos, campos, BindingFlags
Un `Type` es un catálogo, y el catálogo enumera sus miembros. Tres métodos desbloquean la mayor parte del trabajo de ins…
Empezar lección - Paso 223
Crear instancias en tiempo de ejecución — Activator.CreateInstance
Inspeccionar un tipo es solo la mitad de la historia; los frameworks también necesitan CONSTRUIR objetos de tipos contra…
Empezar lección - Paso 224
Invocar miembros — get/set de propiedades y llamadas dinámicas a métodos
Ahora leemos y escribimos objetos cuya forma descubrimos en tiempo de ejecución. Un `PropertyInfo` expone dos métodos fu…
Empezar lección - Paso 225
Atributos personalizados — adjuntar tus propios metadatos
Los atributos son la forma de agregar metadatos extra a tu código de manera declarativa — las anotaciones entre corchete…
Empezar lección - Paso 226
Leer atributos — convertir metadatos en comportamiento
Un atributo que nadie lee es mera decoración. La recompensa llega cuando la reflexión vuelve a sacar los metadatos en ti…
Empezar lección - Paso 227
Un validador basado en atributos
Ahora ensamblamos las piezas en una funcionalidad que se siente como un framework real: la validación declarativa. La id…
Empezar lección - Paso 228
Genéricos y reflexión — cerrar tipos abiertos en tiempo de ejecución
Los genéricos y la reflexión se encuentran en un punto sutil. Una definición de tipo genérico como `List<>`, sin argumen…
Empezar lección - Paso 229
El costo de la reflexión — y cómo eliminarlo con una caché
La reflexión es cómoda, pero no es barata. Cada operación reflexiva hace un trabajo que una llamada directa se ahorra: b…
Empezar lección - Paso 230
Capstone — un mini-serializador basado en atributos
Todo lo de este capítulo converge en un motor pequeño pero realmente útil: un serializador reflexivo guiado por un atrib…
Empezar lección
Domina la evaluación perezosa: construye secuencias con yield, compón operadores estilo LINQ, transmite de forma asíncrona y evita las trampas de la ejecución diferida.
- Paso 231
IEnumerable<T>, IEnumerator<T> y lo que foreach hace realmente
Ya has escrito cientos de bucles `foreach`, pero quizá nunca te hayas preguntado en qué se compila realmente un `foreach…
Empezar lección - Paso 232
yield return — secuencias perezosas y la máquina de estados del compilador
Implementar `IEnumerator<T>` a mano (llevar un campo de posición, escribir `MoveNext`, exponer `Current`, gestionar `Dis…
Empezar lección - Paso 233
yield break, yield condicional y terminación anticipada
`yield return` produce un elemento; su compañero `yield break;` termina la secuencia. Llegar a `yield break` hace que el…
Empezar lección - Paso 234
Generadores infinitos, Take y evaluación diferida
Como un iterador calcula cada elemento solo cuando se le pide, no necesita tener un final. Un iterador construido alrede…
Empezar lección - Paso 235
Iteradores personalizados — IEnumerable<T> a mano frente al atajo de yield
Para apreciar de verdad `yield`, ayuda escribir un enumerador a la antigua al menos una vez. Supón que construyes un tip…
Empezar lección - Paso 236
Componer iteradores — construye Map y Filter al estilo LINQ con yield
Los iteradores se componen. Como cada iterador CONSUME un `IEnumerable<T>` y a la vez PRODUCE un `IEnumerable<T>`, puede…
Empezar lección - Paso 237
Flujos asíncronos — IAsyncEnumerable<T> y await foreach
Los iteradores ordinarios son síncronos: cada `MoveNext()` produce su elemento de inmediato. Pero los datos reales suele…
Empezar lección - Paso 238
Lotes, paginación y ventanas con yield
Toda una familia de operadores útiles divide un flujo en grupos sin materializar nunca el flujo completo. El BATCHING (a…
Empezar lección - Paso 239
Trampas de los iteradores — ejecución diferida, enumeración múltiple y efectos secundarios
La evaluación perezosa es una herramienta afilada, y el mismo aplazamiento que hace eficientes a los iteradores provoca …
Empezar lección - Paso 240
Capstone — un pipeline perezoso de procesamiento de datos con iteradores personalizados
Es hora de reunir todo el capítulo en un único pipeline perezoso. Leerás un flujo de enteros, los pasarás por una cadena…
Empezar lección
Funciones puras, lambdas de primera clase, composición, inmutabilidad, Result/Option, pattern matching y LINQ como caja de herramientas funcional.
- Paso 241
La mentalidad funcional — funciones puras y transparencia referencial
La programación funcional (FP) no es tanto una característica que activas como una forma de pensar sobre tu código. La i…
Empezar lección - Paso 242
Funciones como valores — Func, Action y funciones de primera clase
El primer cambio concreto hacia la FP es tratar las funciones como valores ordinarios. En C# puedes guardar una función …
Empezar lección - Paso 243
Funciones de orden superior — map, filter y reduce
Una función de orden superior es aquella que recibe una función como argumento, devuelve una función, o ambas cosas. Una…
Empezar lección - Paso 244
Composición y currying — construir funciones a partir de funciones
Una vez que las funciones son valores, puedes construir funciones MÁS GRANDES a partir de otras más pequeñas sin llegar …
Empezar lección - Paso 245
La inmutabilidad en la práctica — readonly, records y with
Las funciones puras necesitan datos inmutables para brillar. Si los valores que fluyen por tu pipeline pueden modificars…
Empezar lección - Paso 246
Estilo con cuerpo de expresión — miembros funcionales concisos
El código funcional se apoya en expresiones más que en sentencias. Una expresión PRODUCE un valor (2 + 3, name.ToUpper()…
Empezar lección - Paso 247
Result y Option — modelar el éxito y el fallo como valores
Las excepciones son la forma imperativa de señalar un fallo: lanzas una y el control salta a algún punto más arriba en l…
Empezar lección - Paso 248
Pattern matching funcional — switch expressions como mecanismo de despacho
El pattern matching es el mecanismo de despacho de la programación funcional: la forma en que un único valor se encamina…
Empezar lección - Paso 249
LINQ como caja de herramientas funcional — pipelines componibles y diferidos
LINQ es la biblioteca estándar funcional de C#, escondida a plena vista. Cada operador que aprendiste en el capítulo 15 …
Empezar lección - Paso 250
Capstone — un pipeline funcional de parseo, validación y transformación
Este capstone fusiona todo el capítulo en un solo programa: un pipeline orientado a vías (railway-oriented) que PARSEA, …
Empezar lección
Toma el control de lo que significa 'lo mismo' y 'va primero': ==, Equals/GetHashCode, IEquatable, IComparable, comparadores, igualdad de records y las trampas que muerden.
- Paso 251
Igualdad — == vs .Equals, por referencia vs por valor
Preguntar "¿son iguales estas dos cosas?" parece trivial hasta que te das cuenta de que C# tiene dos respuestas completa…
Empezar lección - Paso 252
Sobrescribir Equals y GetHashCode juntos
Cuando la igualdad por identidad predeterminada no es la adecuada para tu tipo, la cambias sobrescribiendo object.Equals…
Empezar lección - Paso 253
IEquatable<T> — igualdad tipada y sin boxing
Sobrescribir object.Equals(object) funciona, pero su firma tiene un costo: recibe object, así que cada comparación oblig…
Empezar lección - Paso 254
IComparable<T> — orden natural y el contrato del signo
La igualdad responde "¿son lo mismo?" El orden responde "¿cuál va primero?" Un tipo expresa su orden natural e integrado…
Empezar lección - Paso 255
IComparer<T> — estrategias de ordenamiento externas y múltiples
IComparable<T> incrusta UN orden natural en un tipo. Pero los datos reales rara vez tienen un único orden correcto: las …
Empezar lección - Paso 256
Ordenamiento — Array.Sort, List.Sort, OrderBy, ThenBy
C# ofrece dos familias de ordenamiento, y saber cuándo recurrir a cada una te ahorra disgustos. Array.Sort y List<T>.Sor…
Empezar lección - Paso 257
IEqualityComparer<T> — claves personalizadas para conjuntos y mapas
Así como IComparer<T> externaliza el orden, IEqualityComparer<T> externaliza la igualdad. Reúne AMBAS mitades del contra…
Empezar lección - Paso 258
Igualdad en records y structs — semántica de valor gratis
Todo lo de las últimas lecciones —sobrescribir Equals, implementar IEquatable<T>, calcular un GetHashCode coherente— es …
Empezar lección - Paso 259
Trampas de la igualdad — claves mutables, discrepancias, floats
El bug de igualdad más peligroso es la CLAVE MUTABLE. Insertas un objeto en un Dictionary o un HashSet y, más tarde, mut…
Empezar lección - Paso 260
Capstone — un catálogo ordenado y sin duplicados
Este capstone fusiona todo el capítulo en un solo pipeline: un tipo de dominio con igualdad por valor COMPLETA alimenta …
Empezar lección
CultureInfo, cadenas de formato de números/fechas/moneda, parseo y operaciones de cadenas según la cultura, IFormattable y la regla de usar siempre InvariantCulture para datos de máquina.
- Paso 261
CultureInfo — por qué el mismo valor se imprime distinto
Un número como un millón y medio no se escribe igual en todas partes del mundo. Un estadounidense escribe 1,500,000.50: …
Empezar lección - Paso 262
Cadenas de formato numérico — estándar y personalizadas
Una vez que puedes pasar una cultura, la siguiente pregunta es QUÉ forma quieres darles a los dígitos. C# responde con l…
Empezar lección - Paso 263
Moneda y porcentaje — los especificadores C y P
Dos especificadores estándar son tan comunes que tienen sus propias letras: C para moneda (currency) y P para porcentaje…
Empezar lección - Paso 264
Cadenas de formato de fecha y hora
Las fechas son aún más sensibles a la cultura que los números, porque cambia el propio ORDEN de los componentes: en Esta…
Empezar lección - Paso 265
Parseo con NumberStyles, DateTimeStyles y la cultura
Formatear convierte un valor en texto; parsear convierte el texto de nuevo en un valor. Ambos deben coincidir en la cult…
Empezar lección - Paso 266
Formato compuesto, alineación e interpolación
Hasta ahora hemos formateado valores sueltos. El formato compuesto ensambla varios en una sola cadena mediante marcadore…
Empezar lección - Paso 267
IFormattable — enséñale a tu propio tipo a formatearse
Todos los tipos numéricos y de fecha integrados entienden las cadenas de formato porque implementan la interfaz IFormatt…
Empezar lección - Paso 268
Operaciones de cadenas sensibles a la cultura y StringComparison
El formato no es el único lugar por donde se cuela la cultura. Comparar, ordenar y pasar cadenas a mayúsculas o a minúsc…
Empezar lección - Paso 269
Trampas de la globalización — la I turca y compañía
Los bugs de globalización comparten una firma: el código funciona perfectamente en la máquina del desarrollador y falla …
Empezar lección - Paso 270
Capstone — un formateador de reportes determinista y sensible a la cultura
Es hora de reunir el capítulo en una sola herramienta: un formateador de reportes que lee partidas (line items) e imprim…
Empezar lección
Rangos de enteros y desbordamiento silencioso, checked vs unchecked, la realidad del punto flotante, dinero con decimal, estrategias de redondeo, la clase Math, operaciones de bits, BigInteger y parseo robusto.
- Paso 271
La familia de los enteros — rangos, MinValue/MaxValue y desbordamiento silencioso
Llevas escribiendo `int` desde el primer capítulo, pero C# ofrece toda una familia de tipos enteros y cada uno hace un c…
Empezar lección - Paso 272
checked y unchecked — decide qué ocurre con el desbordamiento
La lección anterior nos dejó un dato preocupante: por defecto, la aritmética de enteros se desborda en silencio. C# te o…
Empezar lección - Paso 273
La realidad del punto flotante — por qué 0.1 + 0.2 no es 0.3
Los enteros son exactos. Los números de punto flotante — `float` (32 bits, ~7 dígitos significativos) y `double` (64 bit…
Empezar lección - Paso 274
decimal — el tipo pensado para el dinero
Si `double` no puede representar 0.1 con exactitud, nunca debes usarlo para dinero. Un centavo que se desvía `0.00000001…
Empezar lección - Paso 275
Redondeo — Math.Round, estrategias para el punto medio, Floor/Ceiling/Truncate
El redondeo parece trivial hasta que te preguntas: ¿a qué se redondea 2.5? Casi todo el mundo dice 3, pero `Math.Round(2…
Empezar lección - Paso 276
La clase Math — Pow, Sqrt, Abs, Clamp y la división entera
La clase estática `System.Math` es la caja de herramientas de funciones numéricas de C#. Todo lo que contiene es un méto…
Empezar lección - Paso 277
Operaciones de bits — &, |, ^, ~, desplazamientos, flags y literales hexadecimales/binarios
Debajo de cada entero hay una fila de bits, y C# te permite operar directamente sobre esos bits. Los operadores a nivel …
Empezar lección - Paso 278
BigInteger — precisión arbitraria cuando long no basta
Incluso `long`, con su techo de 9.2 trillones, acaba quedándose corto. El factorial de 21 ya desborda un `long`; las cla…
Empezar lección - Paso 279
Parseo y conversión — Parse, TryParse, Convert y conversión de base
La entrada llega como texto — desde la consola, un archivo, una petición HTTP — y tienes que convertir ese texto en núme…
Empezar lección - Paso 280
Capstone — una calculadora de precisión
Es hora de reunir el capítulo en una herramienta pequeña pero rigurosa: una calculadora de precisión que elige el compor…
Empezar lección
Más allá de List y Dictionary: pilas, colas, listas enlazadas, colecciones ordenadas y de prioridad, vistas de solo lectura, inmutabilidad y cómo elegir el contenedor correcto.
- Paso 281
El panorama de las colecciones — elegir un contenedor
En el capítulo 7 conociste los tres caballos de batalla de las colecciones de C#: List<T> para una secuencia ordenada qu…
Empezar lección - Paso 282
Stack<T> y Queue<T> — LIFO y FIFO
Dos de las colecciones más útiles modelan tanto cómo salen los elementos como cómo entran. Un Stack<T> es Last-In-First-…
Empezar lección - Paso 283
LinkedList<T> — nodos y empalmes en O(1)
Una List<T> almacena sus elementos en un único bloque contiguo de memoria. Eso hace que el acceso por índice sea instant…
Empezar lección - Paso 284
SortedDictionary<K,V> y SortedSet<T> — siempre en orden
Dictionary<K,V> y HashSet<T> se basan en hashing, lo que ofrece búsquedas en O(1) en promedio pero ningún orden intrínse…
Empezar lección - Paso 285
PriorityQueue<TElement,TPriority> — primero lo urgente
Una Queue<T> simple atiende los elementos estrictamente en orden de llegada. Pero los planificadores reales se fijan en …
Empezar lección - Paso 286
Dictionary a fondo — funcionamiento interno, inicialización, GroupBy, ToLookup
Dictionary<K,V> es la colección con claves más usada de .NET, así que vale la pena entender cómo funciona. Internamente …
Empezar lección - Paso 287
Vistas de solo lectura — exponer colecciones de forma segura
El encapsulamiento (capítulo 5) dice que una clase controla su propio estado. Pero las colecciones dejan escapar ese con…
Empezar lección - Paso 288
Colecciones inmutables — nunca cambian después de construirse
Una VISTA de solo lectura (lección anterior) impide que quien la usa mute una colección a través de una referencia, pero…
Empezar lección - Paso 289
Elegir una colección — una guía de decisión
Ya conoces toda la familia, así que la verdadera habilidad está en elegir. La mejor pregunta posible es: ¿qué operacione…
Empezar lección - Paso 290
Capstone — un planificador de tareas con las colecciones adecuadas
Es hora de poner a trabajar a toda la familia. Vas a construir un pequeño PLANIFICADOR DE TAREAS que procesa un flujo de…
Empezar lección
Los patrones clásicos de la Gang of Four contados en C# moderno e idiomático: Strategy, Factory, Builder, Singleton, Observer, Decorator, Adapter y Command — con Func/Action en lugar de ceremonia de interfaces, y el criterio para saber cuándo NO usarlos.
- Paso 291
Qué son los patrones de diseño — y cuándo NO recurrir a ellos
Un patrón de diseño es una solución con nombre y reutilizable a un problema que aparece una y otra vez en el código orie…
Empezar lección - Paso 292
Strategy — comportamiento intercambiable, con interfaz o Func<>
El patrón Strategy te permite elegir un algoritmo en tiempo de ejecución tratando el propio algoritmo como un objeto que…
Empezar lección - Paso 293
Factory Method — centraliza la creación y devuelve por abstracción
Una Factory es cualquier pieza de código cuyo trabajo es *crear objetos* para que el resto del programa no tenga que sab…
Empezar lección - Paso 294
Builder — construcción paso a paso y configuración fluida
El patrón Builder separa *cómo* se ensambla un objeto de la representación del propio objeto, de modo que los mismos pas…
Empezar lección - Paso 295
Singleton — una única instancia bien hecha, y por qué la DI suele ser mejor
El patrón Singleton garantiza que una clase tenga exactamente una instancia y le da a todo el programa un único punto de…
Empezar lección - Paso 296
Observer — publicar/suscribir, y los eventos de C# son el Observer de GoF
El patrón Observer permite que un objeto (el *sujeto* o *publicador*) notifique a un conjunto cambiante de objetos depen…
Empezar lección - Paso 297
Decorator — envuelve un objeto para agregar comportamiento y luego compón capas
El patrón Decorator agrega responsabilidades a un objeto *envolviéndolo* en otro objeto que comparte la misma interfaz, …
Empezar lección - Paso 298
Adapter — haz que encaje una interfaz incompatible
El patrón Adapter envuelve un objeto cuya interfaz tu código *no puede usar* en una capa delgada que expone la interfaz …
Empezar lección - Paso 299
Command — una acción como objeto (deshacer, colas, historial)
El patrón Command convierte *una petición de hacer algo* en un objeto de primera clase: la acción, sus parámetros y (opc…
Empezar lección - Paso 300
Capstone — un pipeline de procesamiento de texto que combina cuatro patrones
Los patrones rara vez aparecen solos — los diseños reales los *componen*, y cada uno resuelve la parte del problema que …
Empezar lección
Construye un intérprete de expresiones funcional: tokenizador, parser de descenso recursivo, AST y un lenguaje calculadora con variables.
- Paso 301
Qué es un intérprete — el pipeline tokens → AST → valor
Un intérprete es un programa que lee otro programa y lo ejecuta. En este capítulo construiremos uno pequeño pero complet…
Empezar lección - Paso 302
Tokenización — convertir un string en una lista de tokens
La primera etapa de cualquier intérprete es el TOKENIZADOR (o lexer). Su trabajo es pequeño y está bien definido: recorr…
Empezar lección - Paso 303
Gramática y precedencia — por qué * se agrupa con más fuerza que +
Una lista de tokens todavía no es una expresión con significado — aún tenemos que decidir cómo se AGRUPAN. ¿2 + 3 * 4 se…
Empezar lección - Paso 304
Un parser de descenso recursivo — código que refleja la gramática
Un parser de descenso recursivo es la forma más directa de convertir una gramática en código: escribes UN método por cad…
Empezar lección - Paso 305
Nodos del AST — una jerarquía de records sealed para el árbol
Hasta ahora el parser calculaba un double directamente. Ahora separamos la ESTRUCTURA del VALOR: el parser construirá un…
Empezar lección - Paso 306
Evaluar el AST — recorrer el árbol con pattern matching
Tenemos un árbol de nodos; ahora calculamos su valor. El evaluador es una sola función recursiva — llamémosla Eval — que…
Empezar lección - Paso 307
Variables y el entorno — un Dictionary de nombres a valores
Una calculadora que solo sabe operar con constantes no pasa de ser un motor aritmético con pretensiones. El salto a un p…
Empezar lección - Paso 308
Manejo de errores en el parser — mensajes claros para entradas incorrectas
La entrada real es desordenada. Los usuarios escriben `(4 + 1` y olvidan el paréntesis de cierre, escriben `3 +` y se de…
Empezar lección - Paso 309
Extender el lenguaje — menos unario y funciones integradas
Da gusto HACER CRECER un intérprete bien estructurado. Como las etapas están separadas y el parser refleja la gramática,…
Empezar lección - Paso 310
Capstone — un intérprete de calculadora completo con variables
Es hora de ensamblar todo el capítulo en un único intérprete funcional. El capstone es un LENGUAJE DE CALCULADORA: un pr…
Empezar lección
Varianza, restricciones avanzadas, matemática genérica (INumber<T>), miembros estáticos abstractos e IParsable<T> — la maquinaria profunda detrás del código reutilizable y con seguridad de tipos.
- Paso 311
Genéricos a fondo — tipos abiertos vs. cerrados
El capítulo 9 presentó los genéricos como la respuesta a "¿cómo escribo una List que funcione con cualquier tipo de elem…
Empezar lección - Paso 312
Covarianza — cuando IEnumerable<Cat> es un IEnumerable<Animal>
Esta es una pregunta que hace tropezar a casi todo el mundo la primera vez: si `Cat` deriva de `Animal`, ¿una `List<Cat>…
Empezar lección - Paso 313
Contravarianza — cuando Action<Animal> es un Action<Cat>
La covarianza fluía en la dirección que tu intuición esperaba: una secuencia de gatos es una secuencia de animales. La c…
Empezar lección - Paso 314
Restricciones avanzadas — combinación y dependencia
Una sola restricción como `where T : IComparable<T>` desbloquea una capacidad. El código genérico real a menudo necesita…
Empezar lección - Paso 315
Matemática genérica — INumber<T> y un único Sum para gobernarlos a todos
Durante dos décadas C# tuvo una carencia vergonzosa: no podías escribir un único método genérico que sumara números. `T …
Empezar lección - Paso 316
Miembros static abstract de interfaz — el motor detrás de la matemática genérica
¿Cómo funciona siquiera `T.Zero`? `Zero` es un miembro ESTÁTICO, y antes de C# 11 una interfaz solo podía declarar miemb…
Empezar lección - Paso 317
IParsable<T> — parseo genérico y el patrón T.Parse
Convertir texto en un valor está en todas partes: leer configuración, columnas CSV, argumentos de comandos, payloads de …
Empezar lección - Paso 318
Delegados genéricos e inferencia de tipos
Los genéricos y los delegados están hechos el uno para el otro. `Func<TIn, TResult>` y `Action<T>` son, en sí mismos, ti…
Empezar lección - Paso 319
Trampas de los genéricos — default(T), boxing y el exceso de genericidad
Los genéricos son potentes, pero hay un puñado de trampas que se repiten con tanta frecuencia que merecen su propia lecc…
Empezar lección - Paso 320
Capstone — un agregador numérico genérico Stats<T>
Es hora de fusionar todo el capítulo en un solo tipo. El capstone construye `Stats<T> where T : INumber<T>`: un agregado…
Empezar lección
qué es una FSM (estados/eventos/transiciones) → función de transición con enum + switch → tablas data-driven Dictionary<(State,Event),State> → transiciones con guardas + acciones de efecto secundario → rechazar eventos ilegales → estados como jerarquía de records sealed → hooks de entrada/salida + registro de transiciones → estados jerárquicos + historial → trampas de las FSM (explosión de estados, sopa de booleanos, transiciones faltantes) → capstone de motor de flujo de pedidos
- Paso 321
¿Qué es una máquina de estados finita?
Una máquina de estados finita (FSM, o simplemente "máquina de estados") es una de las ideas más antiguas y útiles de la …
Empezar lección - Paso 322
La FSM más sencilla — un enum y un switch
Usar strings sueltos para los estados, como hicimos en la lección anterior, funciona pero es frágil: un error tipográfic…
Empezar lección - Paso 323
Tablas de transiciones guiadas por datos
Un `switch` es código; una TABLA de transiciones son datos. Cuando una máquina supera un puñado de transiciones, el swit…
Empezar lección - Paso 324
Transiciones con guarda y acciones con efectos secundarios
Hasta ahora, una transición dependía solo del estado actual y del evento. Pero las máquinas reales a menudo también nece…
Empezar lección - Paso 325
Rechazar eventos ilegales
Hasta ahora, nuestro caso comodín no ha hecho nada, en silencio, ante pares (estado, evento) desconocidos. Esa política …
Empezar lección - Paso 326
Estados como una jerarquía de records sellados
Un enum nombra los estados de maravilla, pero no puede transportar datos. Un estado Connecting podría querer recordar cu…
Empezar lección - Paso 327
Hooks de entrada, de salida y de transición
Una vez que una máquina tiene estados interesantes, a menudo quieres que algo ocurra cada vez que ENTRAS en un estado o …
Empezar lección - Paso 328
Estados jerárquicos e historial
Las máquinas de estados planas explotan cuando varios estados comparten un comportamiento común. Imagina un temporizador…
Empezar lección - Paso 329
Trampas — cuándo una FSM ayuda y cuándo perjudica
Las máquinas de estados no son gratis, y recurrir a una por reflejo es un error en sí mismo. La trampa más común es la E…
Empezar lección - Paso 330
Capstone — un motor de flujos de trabajo para pedidos
Es hora de ensamblar todo lo que enseñó este capítulo en un pequeño motor de flujos de trabajo. Construirás una FSM de p…
Empezar lección
Modela el dominio con tipos para que los estados ilegales sean irrepresentables
- Paso 331
Modelar el dominio, no la base de datos
La mayoría de los bugs no son errores de tipeo ni fallos por uno (off-by-one): son el programa haciendo en silencio lo i…
Empezar lección - Paso 332
Value objects — igualdad por contenido
Un *value object* (objeto de valor) es un tipo pequeño e inmutable que no tiene identidad propia: se define por completo…
Empezar lección - Paso 333
Entidades vs value objects — identidad vs contenido
La decisión de modelado más importante que tomas para cualquier concepto es esta: ¿tiene *identidad* o se define únicame…
Empezar lección - Paso 334
Hacer que los estados ilegales sean irrepresentables
La técnica central de este capítulo tiene un nombre fácil de recordar: *make illegal states unrepresentable* (haz que lo…
Empezar lección - Paso 335
Smart constructors — validar en la creación
Un *smart constructor* (constructor inteligente) es el mecanismo que convierte "illegal states unrepresentable" de una a…
Empezar lección - Paso 336
Invariantes y encapsulación
Una *invariante* es una regla que debe cumplirse durante toda la vida de un objeto: el saldo de una cuenta nunca baja de…
Empezar lección - Paso 337
Conjuntos cerrados — enums vs jerarquías sealed
Muchos conceptos de dominio son un *conjunto cerrado de opciones*: un semáforo está en Red, Amber o Green; un pago se ha…
Empezar lección - Paso 338
Agregados y la frontera de consistencia
A medida que los modelos crecen, los objetos empiezan a agruparse: un `Order` es dueño de sus `LineItem`s; un `Cart` es …
Empezar lección - Paso 339
Eventos de dominio — registrar lo que ocurrió
Hasta ahora, nuestros modelos capturan el *estado actual* del dominio. Pero al negocio a menudo le importa igual de much…
Empezar lección - Paso 340
Capstone — modela un pequeño dominio de pedidos
Este capstone entrelaza todos los hilos del capítulo en un dominio pequeño y fiable. Modelarás un carrito de compras / p…
Empezar lección
el pipeline de peticiones → Minimal APIs → routing y binding de parámetros → inyección de dependencias y lifetimes → middleware → model binding y validación → controllers vs minimal → códigos de estado, results y ProblemDetails → configuración y auth → capstone Catalog Web API
- Paso 341
ASP.NET Core — what a web framework actually does
Everything you have learned so far runs in a console: a process starts, your code runs top to bottom, it prints, it exit…
Empezar lección - Paso 342
Minimal APIs — endpoints como lambdas
Un endpoint de Minimal API es una ruta emparejada con un handler (manejador). El handler es solo un delegado —normalment…
Empezar lección - Paso 343
Enrutamiento y binding de parámetros
El enrutamiento (routing) es el proceso de hacer coincidir el método y la ruta de una petición entrante con exactamente …
Empezar lección - Paso 344
Inyección de dependencias y ciclos de vida de los servicios
La inyección de dependencias (DI) es la columna vertebral de ASP.NET Core. En lugar de que una clase se encargue de cons…
Empezar lección - Paso 345
El pipeline de middleware
Cada petición fluye a través de un pipeline de middleware antes de llegar a tu endpoint, y vuelve a salir por los mismos…
Empezar lección - Paso 346
Model binding y validación
Ya viste cómo el binding extrae valores simples de la ruta y del query string. El caso más rico es enlazar un objeto com…
Empezar lección - Paso 347
Controllers — the class-based alternative
Before Minimal APIs, every ASP.NET Core endpoint lived in a controller — a class that groups related actions as methods.…
Empezar lección - Paso 348
Códigos de estado, resultados y ProblemDetails
El código de estado HTTP es lo primero que lee un cliente, y elegirlo correctamente marca la diferencia entre una API so…
Empezar lección - Paso 349
Configuración y fundamentos de autenticación
Un servicio real necesita ajustes que cambian entre entornos —una cadena de conexión, una API key, un feature toggle— si…
Empezar lección - Paso 350
Capstone — una Web API de catálogo completa
Este capstone reúne todo el capítulo en un único servicio coherente: un catálogo de productos en memoria con CRUD comple…
Empezar lección
qué es un ORM → DbContext y entidades → configurar el modelo (anotaciones vs Fluent API) → migraciones → consultas con LINQ (IQueryable → SQL) → CRUD y el change tracker → relaciones → carga de datos relacionados (Include / N+1) → tracking y rendimiento → capstone de modelo de datos
- Paso 351
Entity Framework Core — what an ORM actually does
Your code thinks in objects: a Product has a Name, a Price, and a list of Reviews, and a Review points back at its Produ…
Empezar lección - Paso 352
DbContext & entities — the session and the tables
The center of every EF Core application is the DbContext. It is two things at once. First, it is a session — a short-liv…
Empezar lección - Paso 353
Configuring the model — annotations vs Fluent API
Conventions get you most of the way, but real schemas need precision: a column should be NVARCHAR(100), not unbounded; a…
Empezar lección - Paso 354
Migrations — evolving the schema safely
Code-first means your C# model is the source of truth, but the database needs an actual schema — tables, columns, indexe…
Empezar lección - Paso 355
Consultar con LINQ-to-Entities
Ya conoces LINQ del capítulo de colecciones. EF Core te permite escribir las mismas queries Where, OrderBy, Select y Gro…
Empezar lección - Paso 356
CRUD y el change tracker
Leer es la mitad de la historia; la otra mitad es escribir. El modelo de escritura de EF Core se basa en el change track…
Empezar lección - Paso 357
Relationships — one-to-many, one-to-one, many-to-many
Real data is connected: a Blog has many Posts, a Post has many Comments, a User has one Profile, a Post has many Tags an…
Empezar lección - Paso 358
Carga de datos relacionados y el problema N+1
Ya tienes propiedades de navegación; ahora la pregunta es cuándo se cargan realmente sus datos desde la base de datos. U…
Empezar lección - Paso 359
Tracking, proyección y rendimiento
Por defecto, cada entidad que devuelve una query queda rastreada (tracked): el DbContext guarda una referencia a ella y …
Empezar lección - Paso 360
Capstone — un modelo de datos Blog/Post/Comment de principio a fin
Este capstone reúne todo el capítulo en un único modelo de datos coherente: un esquema de blogs con Blogs, Posts y Comme…
Empezar lección
el Generic Host → configuración y el patrón Options → logging (ILogger) → servicios en segundo plano → IHttpClientFactory → resiliencia (reintentos, circuit breaker, timeout) → gRPC → SignalR en tiempo real → mensajería y colas → capstone de worker service resiliente
- Paso 361
The Generic Host — one bootstrap to rule them all
Every non-trivial .NET application — a web API, a console worker, a desktop app that needs background services — shares …
Empezar lección - Paso 362
Proveedores de configuración y el patrón Options
Un servicio desplegable debe cambiar de comportamiento entre entornos —una cadena de conexión, un nombre de cola, un núm…
Empezar lección - Paso 363
Logging with ILogger<T> & structured logs
In a console app you reach for Console.WriteLine; in a service you must not. A running service is observed from the outs…
Empezar lección - Paso 364
Servicios en segundo plano y el bucle de ExecuteAsync
Un servicio en segundo plano es trabajo que se ejecuta durante toda la vida de la aplicación, independiente de cualquier…
Empezar lección - Paso 365
IHttpClientFactory — calling other services right
A distributed system is mostly services calling other services over HTTP, and HttpClient is how C# makes those calls. It…
Empezar lección - Paso 366
Resiliencia — reintentos, backoff y circuit breakers
En un sistema distribuido, el fallo no es una excepción: es el clima habitual. Se pierde un paquete de red, una base de …
Empezar lección - Paso 367
gRPC — strongly-typed service contracts
REST over JSON is the lingua franca of public web APIs, but for service-to-service calls inside a system there is often …
Empezar lección - Paso 368
SignalR — real-time server-to-client push
Most of the web is request/response: the client asks, the server answers, the connection closes. But some features need …
Empezar lección - Paso 369
Mensajería asíncrona — colas, topics e idempotencia
Las llamadas directas —HTTP, gRPC— acoplan dos servicios en el tiempo: el que llama espera al servicio llamado y, si est…
Empezar lección - Paso 370
Capstone — un Worker Service distribuido y resiliente
Este capstone reúne todo el capítulo —y buena parte del curso— en un único sistema coherente: un Worker Service que cons…
Empezar lección
qué es Blazor → componentes Razor → data binding (@bind) → manejo de eventos (EventCallback) → ciclo de vida del componente → render y estado → formularios y validación → modelos de render (Server / WebAssembly / Auto) → interop con JavaScript → capstone de componente interactivo
- Paso 371
Blazor — what it is and where it fits
For decades, building an interactive web page meant writing the back end in one language and the front end in JavaScript…
Empezar lección - Paso 372
Razor components — markup, @code, and parameters
A Razor component is a reusable unit of UI, and its anatomy is simple: a .razor file containing HTML-like markup interle…
Empezar lección - Paso 373
Enlace de datos — renderizado unidireccional y @bind bidireccional
El binding conecta el estado C# de tu componente con lo que el usuario ve y escribe. La dirección más simple es la unidi…
Empezar lección - Paso 374
Manejo de eventos y EventCallback
Interactividad significa responder a lo que hace el usuario, y en Blazor cada evento del DOM se corresponde con un atrib…
Empezar lección - Paso 375
The component lifecycle
Every component goes through a predictable sequence of lifecycle events from the moment Blazor creates it to the moment …
Empezar lección - Paso 376
Renderizado, el render tree y compartir estado
Cuando un componente de Blazor se renderiza, no tira la página para reconstruirla. Produce un render tree (árbol de rend…
Empezar lección - Paso 377
Forms & validation
Forms are where most real interactivity lives, and Blazor has a dedicated component for them: EditForm. Instead of wirin…
Empezar lección - Paso 378
Render models — Server, WebAssembly & Auto
You have built components without worrying where they run; now it is time to choose. Blazor's three interactive render m…
Empezar lección - Paso 379
JavaScript interop
Blazor lets you write nearly all of your UI in C#, but the browser's own capabilities — local storage, the clipboard, th…
Empezar lección - Paso 380
Capstone — un dashboard interactivo de Todo
Este capstone reúne todo el capítulo en una única funcionalidad coherente: un dashboard interactivo de Todo construido a…
Empezar lección
qué es WPF → fundamentos de XAML → paneles de layout → controles y el modelo de contenido → propiedades de dependencia → data binding + INotifyPropertyChanged → el patrón MVVM → ICommand / RelayCommand → ObservableCollection y plantillas → capstone de app MVVM
- Paso 381
WPF — what a desktop UI framework actually does
Everything you have built so far either ran in a console or served HTTP from a server. A desktop application is a third …
Empezar lección - Paso 382
XAML — markup that is really an object graph
XAML (Extensible Application Markup Language, pronounced "zammel") looks like HTML but it is something more precise: it …
Empezar lección - Paso 383
Layout — the measure/arrange system and the panels
WPF does not place controls at fixed pixel coordinates the way old toolkits did. Instead it runs a two-pass layout algor…
Empezar lección - Paso 384
Controls, content & templates
WPF controls are built around a content model that is far more flexible than older toolkits, and grasping it unlocks mos…
Empezar lección - Paso 385
Dependency properties — the property system behind WPF
Almost every property you set in XAML — Width, Background, Text, IsEnabled — is not an ordinary C# property with a priva…
Empezar lección - Paso 386
Enlace de datos — mantener la UI y tus datos sincronizados
El data binding es la característica que hace que WPF valga la pena, y es el motor sobre el que se apoya MVVM. Un bindin…
Empezar lección - Paso 387
MVVM — the architecture that organizes a WPF app
MVVM — Model-View-ViewModel — is the architectural pattern that WPF was designed for, and it falls out almost inevitably…
Empezar lección - Paso 388
Comandos — exponer acciones al estilo MVVM
El binding se ocupa de los datos —una propiedad que entra, una propiedad que sale—, pero una aplicación también tiene ac…
Empezar lección - Paso 389
Colecciones observables — listas que mantienen la UI al día
Un view model que muestra una lista —contactos, pedidos, resultados de búsqueda— necesita exponer esa lista a un ItemsCo…
Empezar lección - Paso 390
Capstone — un editor de contactos MVVM completo
Este capstone reúne todo el capítulo en una única aplicación coherente: un pequeño editor de contactos que te permite ag…
Empezar lección
qué es Unity → el ciclo de vida de MonoBehaviour → GameObjects y componentes → vectores y transforms → manejo de input → física y colisiones → prefabs e instanciación → Time.deltaTime y movimiento → estado del juego y UI → capstone de juego arcade
- Paso 391
Unity — what a game engine actually gives you
Everything you have built so far either ran top to bottom and exited (a console app) or woke up to answer a request and …
Empezar lección - Paso 392
The MonoBehaviour lifecycle — when your code runs
A MonoBehaviour is not driven by you calling its methods — it is driven by Unity calling yours, at precise moments, in a…
Empezar lección - Paso 393
GameObjects & Components — composition in practice
Now that you know a GameObject is a bag of Components, the day-to-day skill is reaching between them: from your script, …
Empezar lección - Paso 394
Vectores y Transforms — la matemática de mover cosas
Posición, dirección, velocidad y fuerza son, en un juego, el mismo tipo de cosa: un vector. El Vector3 de Unity es un st…
Empezar lección - Paso 395
Reading input — turning keys into movement
A game is a conversation: the player presses, the game responds, every frame. Reading that input is the bridge between t…
Empezar lección - Paso 396
Physics & collision — Rigidbodies and Colliders
Up to now you moved objects by writing transform.position directly — teleporting them. That is fine for things that igno…
Empezar lección - Paso 397
Prefabs & instantiation — spawning at runtime
Most games create objects while they run: a gun fires bullets, a spawner releases enemies, an explosion throws debris. Y…
Empezar lección - Paso 398
Tiempo y movimiento — independencia del frame rate
Este es el número más importante de la programación de juegos en tiempo real: Time.deltaTime, la cantidad de segundos tr…
Empezar lección - Paso 399
Estado del juego, UI y gestión de escenas
Un juego es más que un personaje que se mueve: es un sistema con modos. El menú principal es un mundo distinto de la par…
Empezar lección - Paso 400
Capstone — conectar el bucle de un pequeño juego arcade
Esta lección final reúne todo el capítulo con la forma de un juego arcade real, aunque diminuto, y, como es la última le…
Empezar lección