<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Manuel Dávila Alarcón</title>
    <description>The latest articles on DEV Community by Manuel Dávila Alarcón (@maadcode).</description>
    <link>https://dev.to/maadcode</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F577901%2F65a16251-cb58-417e-aece-a65d1413684a.png</url>
      <title>DEV Community: Manuel Dávila Alarcón</title>
      <link>https://dev.to/maadcode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maadcode"/>
    <language>en</language>
    <item>
      <title>Todo lo que necesitas saber para publicar NuGets</title>
      <dc:creator>Manuel Dávila Alarcón</dc:creator>
      <pubDate>Mon, 15 Dec 2025 15:53:23 +0000</pubDate>
      <link>https://dev.to/maadcode/todo-lo-que-necesitas-saber-para-publicar-nugets-17j</link>
      <guid>https://dev.to/maadcode/todo-lo-que-necesitas-saber-para-publicar-nugets-17j</guid>
      <description>&lt;p&gt;En el &lt;a href="https://dev.to/maadcode/domina-el-uso-de-paquetes-nuget-en-net-g4k"&gt;artículo anterior&lt;/a&gt;, analizamos cómo sobrevivir al infierno de las dependencias desde la perspectiva del consumidor. Sin embargo, el verdadero salto de calidad en una carrera técnica ocurre cuando dejas de ser quien descarga paquetes y te conviertes en quien los diseña.&lt;/p&gt;

&lt;p&gt;El problema fundamental que resuelve NuGet no es simplemente &lt;em&gt;"bajar DLLs"&lt;/em&gt;, sino la violación del principio DRY (Don't Repeat Yourself) a nivel arquitectónico.&lt;/p&gt;

&lt;p&gt;Imagina el escenario clásico donde tienes una clase &lt;code&gt;AuditLog.cs&lt;/code&gt; o un &lt;code&gt;StringUtils.cs&lt;/code&gt;. Al iniciar un nuevo microservicio, lo más "rápido" es copiar y pegar el archivo. Seis meses después, encuentras un bug crítico de seguridad en esa clase. Ahora te enfrentas a la pesadilla de auditar y parchear 10 repositorios distintos manualmente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fopdpqz70qw9zquqviqfe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fopdpqz70qw9zquqviqfe.png" alt="Meme: Code Duplication" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La solución profesional es empaquetarlo y vamos a descubrir como hacerlo con NuGet.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. NuGet Library
&lt;/h2&gt;

&lt;p&gt;Crear una librería no requiere magia, requiere &lt;strong&gt;metadatos&lt;/strong&gt;. El archivo &lt;code&gt;.csproj&lt;/code&gt; deja de ser un simple archivo de configuración para convertirse en el &lt;strong&gt;manifiesto del producto&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Si el &lt;code&gt;.dll&lt;/code&gt; es el producto, el &lt;code&gt;.csproj&lt;/code&gt; es la etiqueta de envío; sin ella, nadie sabrá qué es, cómo se usa ni si es seguro.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Aquí tienes una configuración explicada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Project&lt;/span&gt; &lt;span class="na"&gt;Sdk=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.NET.Sdk"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- MULTI-TARGETING --&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- netstandard2.0 para compatibilidad máxima (Legacy) --&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- net8.0 para optimizaciones modernas --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;TargetFrameworks&amp;gt;&lt;/span&gt;netstandard2.0;net8.0&lt;span class="nt"&gt;&amp;lt;/TargetFrameworks&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- IDENTIDAD --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageId&amp;gt;&lt;/span&gt;MyCompany.Common&lt;span class="nt"&gt;&amp;lt;/PackageId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Version&amp;gt;&lt;/span&gt;1.0.0&lt;span class="nt"&gt;&amp;lt;/Version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Authors&amp;gt;&lt;/span&gt;Equipo de Arquitectura&lt;span class="nt"&gt;&amp;lt;/Authors&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Company&amp;gt;&lt;/span&gt;Mi Empresa S.A.&lt;span class="nt"&gt;&amp;lt;/Company&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Description&amp;gt;&lt;/span&gt;Librería base para validaciones y logs estandarizados.&lt;span class="nt"&gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- ASSETS --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageIcon&amp;gt;&lt;/span&gt;icon.png&lt;span class="nt"&gt;&amp;lt;/PackageIcon&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageReadmeFile&amp;gt;&lt;/span&gt;README.md&lt;span class="nt"&gt;&amp;lt;/PackageReadmeFile&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- SEGURIDAD --&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Garantiza que el binario sea idéntico bit a bit en cada build --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ContinuousIntegrationBuild&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/ContinuousIntegrationBuild&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- ORGANIZACIÓN --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageTags&amp;gt;&lt;/span&gt;logs;validation;common;architecture&lt;span class="nt"&gt;&amp;lt;/PackageTags&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageOutputPath&amp;gt;&lt;/span&gt;./nupkg&lt;span class="nt"&gt;&amp;lt;/PackageOutputPath&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- REPOSITORIO Y LICENCIA --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;RepositoryUrl&amp;gt;&lt;/span&gt;https://github.com/mi-empresa/my-common-lib&lt;span class="nt"&gt;&amp;lt;/RepositoryUrl&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;RepositoryType&amp;gt;&lt;/span&gt;git&lt;span class="nt"&gt;&amp;lt;/RepositoryType&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageLicenseExpression&amp;gt;&lt;/span&gt;MIT&lt;span class="nt"&gt;&amp;lt;/PackageLicenseExpression&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- BUILD --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;GeneratePackageOnBuild&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/GeneratePackageOnBuild&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;IncludeSymbols&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/IncludeSymbols&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SymbolPackageFormat&amp;gt;&lt;/span&gt;snupkg&lt;span class="nt"&gt;&amp;lt;/SymbolPackageFormat&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- DEPENDENCIAS --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ItemGroup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Serilog"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"4.0.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;ItemGroup&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Empaquetamos los assets visuales dentro del nupkg --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;None&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"..\images\icon.png"&lt;/span&gt; &lt;span class="na"&gt;Pack=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="na"&gt;PackagePath=&lt;/span&gt;&lt;span class="s"&gt;"\"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;None&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"..\README.md"&lt;/span&gt; &lt;span class="na"&gt;Pack=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="na"&gt;PackagePath=&lt;/span&gt;&lt;span class="s"&gt;"\"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ¿Por qué cada línea importa?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  🎯 El Dilema del Target (Multi-targeting)
&lt;/h4&gt;

&lt;p&gt;¿Tu empresa tiene proyectos viejos en .NET Framework y nuevos en .NET 8? No elijas uno.&lt;br&gt;
Usando &lt;code&gt;&amp;lt;TargetFrameworks&amp;gt;&lt;/code&gt; (en plural), compilas para ambos.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;netstandard2.0:&lt;/strong&gt; Corre en casi cualquier cosa (incluso .NET Framework 4.6.1+).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;net8.0:&lt;/strong&gt; Aprovecha las optimizaciones modernas de rendimiento.
&lt;em&gt;NuGet entregará automáticamente la DLL correcta según el proyecto del consumidor.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  📁 Assets (Icon &amp;amp; Readme)
&lt;/h4&gt;

&lt;p&gt;Agrega personalización y documentación de tu package (al menos si será público).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PackageIcon:&lt;/strong&gt; Incluye tu logo (png 128x128).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PackageReadmeFile:&lt;/strong&gt; El &lt;code&gt;README.md&lt;/code&gt; se mostrará en la pestaña de NuGet en Visual Studio. Es tu oportunidad de explicar cómo usar la librería antes de que el dev se frustre y la desinstale.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  🔒 Builds Deterministas
&lt;/h4&gt;

&lt;p&gt;¿Te ha pasado que compilas lo mismo dos veces y el hash cambia?&lt;br&gt;
&lt;code&gt;&amp;lt;ContinuousIntegrationBuild&amp;gt;true&amp;lt;/ContinuousIntegrationBuild&amp;gt;&lt;/code&gt; garantiza que si el código no cambia, el binario es idéntico bit a bit. Esto es crucial para validaciones de seguridad y cachés en entornos corporativos.&lt;/p&gt;
&lt;h4&gt;
  
  
  📦 Dependencias Transitivas
&lt;/h4&gt;

&lt;p&gt;Al incluir &lt;code&gt;Serilog&lt;/code&gt; en el &lt;code&gt;ItemGroup&lt;/code&gt;, cualquiera que instale tu paquete lo recibirá automáticamente. ¡No obligues a tus usuarios a instalar dependencias manualmente!&lt;/p&gt;
&lt;h4&gt;
  
  
  🏷️ Etiquetas de repositorio
&lt;/h4&gt;

&lt;p&gt;Si omites esto, tu paquete se verá "sospechoso" en los feeds. Vincular el código fuente demuestra profesionalismo y permite a los usuarios (o auditores) navegar al repo original con un clic.&lt;/p&gt;
&lt;h4&gt;
  
  
  🗂️ Estrategia de versionamiento
&lt;/h4&gt;

&lt;p&gt;Si bien aquí usamos una versión estática (1.0.0), en entornos profesionales te sugiero automatizar esto con herramientas como &lt;strong&gt;MinVer&lt;/strong&gt;, que calculan la versión semántica basándose en tus Git Tags.&lt;/p&gt;
&lt;h4&gt;
  
  
  ⚖️ Licenciamiento Legal
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open Source:&lt;/strong&gt; Usa &lt;code&gt;&amp;lt;PackageLicenseExpression&amp;gt;&lt;/code&gt; con códigos estándar como MIT, Apache-2.0, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Propietario/Empresarial:&lt;/strong&gt; Usa &lt;code&gt;&amp;lt;PackageLicenseFile&amp;gt;&lt;/code&gt; y apunta a un archivo LICENSE.txt dentro del paquete para proteger la propiedad intelectual de tu empresa.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff8wqzd75j3qu54a0hxg1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff8wqzd75j3qu54a0hxg1.png" alt="Diagrama de creación de nupkg" width="800" height="237"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  2. NuGet Tools
&lt;/h2&gt;

&lt;p&gt;Mientras que las librerías se integran en tu aplicación, las NuGet Tools son aplicaciones que corren junto a tu aplicación. Piensa en herramientas como &lt;code&gt;dotnet-ef&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Podemos crear nuestras propias herramientas corporativas (por ejemplo, un Scaffolder para crear microservicios con la arquitectura de la empresa) empaquetando una aplicación de consola.&lt;/p&gt;
&lt;h3&gt;
  
  
  PackAsTool
&lt;/h3&gt;

&lt;p&gt;La diferencia técnica radica en la propiedad &lt;code&gt;&amp;lt;PackAsTool&amp;gt;&lt;/code&gt;. Esto le dice a NuGet que el paquete contiene un ejecutable, no una librería para referenciar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Project&lt;/span&gt; &lt;span class="na"&gt;Sdk=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.NET.Sdk"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;OutputType&amp;gt;&lt;/span&gt;Exe&lt;span class="nt"&gt;&amp;lt;/OutputType&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;TargetFramework&amp;gt;&lt;/span&gt;net10.0&lt;span class="nt"&gt;&amp;lt;/TargetFramework&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Convierte la consola en una herramienta distribuible --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackAsTool&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/PackAsTool&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Este es el comando mágico que escribirás en la terminal --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ToolCommandName&amp;gt;&lt;/span&gt;my-scaffolder&lt;span class="nt"&gt;&amp;lt;/ToolCommandName&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;PackageId&amp;gt;&lt;/span&gt;MyCompany.Scaffolder&lt;span class="nt"&gt;&amp;lt;/PackageId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Version&amp;gt;&lt;/span&gt;1.0.0&lt;span class="nt"&gt;&amp;lt;/Version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageOutputPath&amp;gt;&lt;/span&gt;./nupkg&lt;span class="nt"&gt;&amp;lt;/PackageOutputPath&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cuando un desarrollador instala este paquete, el ejecutable se añade al PATH del sistema y queda disponible como un comando nativo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Instalación Global&lt;/span&gt;
dotnet tool &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; MyCompany.Scaffolder

&lt;span class="c"&gt;# 2. Ejecución&lt;/span&gt;
my-scaffolder &lt;span class="s2"&gt;"NuevoServicio"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 Para evitar la instalación global puedes usar &lt;strong&gt;Local Tools&lt;/strong&gt; (&lt;code&gt;dotnet new tool-manifest&lt;/code&gt;) para asegurar que todos usen la misma versión mediante &lt;code&gt;dotnet tool restore&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3. Estrategias de distribución
&lt;/h2&gt;

&lt;p&gt;Tener el artefacto .nupkg es solo el primer paso. La decisión crítica es dónde debe alojarse.&lt;/p&gt;

&lt;p&gt;Para publicar, necesitamos registrar los destinos en nuestro &lt;code&gt;NuGet.config&lt;/code&gt;. Este archivo actúa como una &lt;em&gt;"libreta de direcciones"&lt;/em&gt; bidireccional: sirve tanto para descargar (restore) como para subir (push).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;packageSources&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;clear&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Estrategia A: Cloud (GitHub, Azure, AWS) --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"github"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"https://nuget.pkg.github.com/TU_ORG/index.json"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Estrategia B: Server NuGet Privado --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"baget"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"http://nuget-server:5555/v3/index.json"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Estrategia C: Pública --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"nuget.org"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"https://api.nuget.org/v3/index.json"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Estrategia D: On-Premise con carpetas compartidas --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"shared"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"\\ServidorWindows\Nugets"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/packageSources&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aquí están las estrategias ordenadas por madurez empresarial:&lt;/p&gt;

&lt;h3&gt;
  
  
  Estrategia A: Cloud Providers
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;El estándar de oro&lt;/strong&gt;, el código fuente vive junto a sus artefactos. Proveedores como &lt;strong&gt;GitHub Packages, Azure Artifacts o AWS CodeArtifacts&lt;/strong&gt; permiten que tus paquetes sean públicos o privados, seguros y accesibles solo mediante autenticación.&lt;/p&gt;

&lt;p&gt;La ventaja clave es la integración con CI/CD: un Pipeline ejecuta los tests y, si pasan, publica automáticamente la nueva versión.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Publicar usando el alias "github" definido en el config&lt;/span&gt;
dotnet nuget push &lt;span class="s2"&gt;"./nupkg/MyCompany.Common.1.0.0.nupkg"&lt;/span&gt; &lt;span class="nt"&gt;--source&lt;/span&gt; &lt;span class="s2"&gt;"github"&lt;/span&gt; &lt;span class="nt"&gt;--api-key&lt;/span&gt; TU_TOKEN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Estrategia B: Server NuGet Privado
&lt;/h3&gt;

&lt;p&gt;La evolución moderna para redes aisladas, levantar un servidor web dedicado como &lt;strong&gt;BaGet&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Esto ofrece indexado rápido, caché, interfaz web para buscar paquetes y compatibilidad con clientes que no son Windows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Publicar usando el alias "baget" definido en el config&lt;/span&gt;
dotnet nuget push &lt;span class="s2"&gt;"./nupkg/MyCompany.Common.1.0.0.nupkg"&lt;/span&gt; &lt;span class="nt"&gt;--source&lt;/span&gt; &lt;span class="s2"&gt;"baget"&lt;/span&gt; &lt;span class="nt"&gt;--api-key&lt;/span&gt; TU_API_KEY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Estrategia C: NuGet.org
&lt;/h3&gt;

&lt;p&gt;Si tu librería resuelve un problema universal y no contiene lógica de negocio propietaria, el destino es nuget.org. Es el repositorio central del ecosistema .NET. Tu código será accesible globalmente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet nuget push &lt;span class="s2"&gt;"./nupkg/MyCompany.Common.1.0.0.nupkg"&lt;/span&gt; &lt;span class="nt"&gt;--source&lt;/span&gt; &lt;span class="s2"&gt;"nuget.org"&lt;/span&gt; &lt;span class="nt"&gt;--api-key&lt;/span&gt; TU_NUGET_API_KEY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Estrategia D: On-Premise con carpetas compartidas
&lt;/h3&gt;

&lt;p&gt;La estrategia clásica &lt;em&gt;"Old School"&lt;/em&gt; en entornos corporativos Windows. Antes de Docker y la Nube, simplemente creábamos una carpeta en un File Server (&lt;code&gt;\\192.168.1.50\Librerias&lt;/code&gt;) y apuntábamos Visual Studio allí.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Publicar usando el alias "shared" definido en el config&lt;/span&gt;
dotnet nuget push &lt;span class="s2"&gt;"./nupkg/MyCompany.Common.1.0.0.nupkg"&lt;/span&gt; &lt;span class="nt"&gt;--source&lt;/span&gt; &lt;span class="s2"&gt;"shared"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwvhaemaqotkmlqet492k.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwvhaemaqotkmlqet492k.gif" alt="Meme: It's been 84 years" width="245" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;La madurez en el desarrollo .NET implica moverse de la duplicación a la modularización.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Usa libraries bien etiquetadas (PackageTags) y licenciadas (PackageLicenseExpression) para centralizar la lógica.&lt;/li&gt;
&lt;li&gt;Usa Tools para distribuir utilidades que mejoren la experiencia de desarrollo (DX).&lt;/li&gt;
&lt;li&gt;Elige la estrategia de distribución que se alinee con tu infraestructura (Nube vs On-Premise).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Empaquetar tu código es una excelente forma de escalar tu impacto como desarrollador.&lt;/p&gt;

&lt;p&gt;¡Happy coding! 🚀&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>dotnet</category>
      <category>nuget</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Domina el uso de paquetes NuGet en .NET</title>
      <dc:creator>Manuel Dávila Alarcón</dc:creator>
      <pubDate>Mon, 15 Dec 2025 11:07:29 +0000</pubDate>
      <link>https://dev.to/maadcode/domina-el-uso-de-paquetes-nuget-en-net-g4k</link>
      <guid>https://dev.to/maadcode/domina-el-uso-de-paquetes-nuget-en-net-g4k</guid>
      <description>&lt;p&gt;¿Alguna vez has entrado a un proyecto Legacy (o incluso uno nuevo mal configurado), intentas compilar y tu consola se tiñe de rojo con errores tipo &lt;code&gt;The type or namespace name 'X' could not be found&lt;/code&gt;? 😵 O peor aún, ¿te ha tocado ese escenario donde el proyecto busca una DLL en una carpeta de red &lt;code&gt;Z:\Librerias&lt;/code&gt; que solo existía en la máquina del desarrollador que renunció hace dos años?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqvfy5l0l2jbk8ea25fsx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqvfy5l0l2jbk8ea25fsx.gif" alt="GIF: This is fine" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si te ha pasado, sabes la frustración de perder horas (o días) solo intentando levantar el entorno. A menudo, el problema no es el código C#, es la gestión de dependencias. Hoy vamos a arreglar esto de raíz, entendiendo &lt;strong&gt;cómo consumir librerías de forma profesional, segura y escalable.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es realmente NuGet?
&lt;/h2&gt;

&lt;p&gt;Imagina que NuGet es el Amazon o Mercado Libre de .NET. Tú no fabricas cada tornillo de tu mueble; los pides a la tienda.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El Package: Es el producto que compras (Newtonsoft.Json, EntityFramework).&lt;/li&gt;
&lt;li&gt;El Source (Feed): Es el almacén o la tienda donde se guardan los paquetes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ¿A dónde van mis paquetes?
&lt;/h2&gt;

&lt;p&gt;Muchos desarrolladores creen que cuando ejecutan &lt;code&gt;dotnet restore&lt;/code&gt;, las DLLs "mágicamente" aparecen en su proyecto. Entender el flujo real es vital para saber qué está pasando por detrás:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Request:&lt;/strong&gt; Tu proyecto (&lt;code&gt;.csproj&lt;/code&gt;) pide &lt;code&gt;Newtonsoft.Json&lt;/code&gt; v13.0.1.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restore:&lt;/strong&gt; NuGet busca en los Sources configurados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global Packages Folder:&lt;/strong&gt; Aquí está el secreto. NuGet descarga y descomprime el paquete en una carpeta global de tu usuario (generalmente &lt;code&gt;%userprofile%\.nuget\packages&lt;/code&gt; en Windows o &lt;code&gt;~/.nuget/packages&lt;/code&gt; en Linux/Mac). &lt;strong&gt;No se guardan dentro de tu proyecto.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build:&lt;/strong&gt; Cuando compilas, .NET lee las DLLs de esa carpeta global y las copia a tu carpeta bin/Debug o bin/Release.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1tlr8ndeaavw28casy9q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1tlr8ndeaavw28casy9q.png" alt="Diagrama de flujo: Ciclo de vida de un paquete NuGet" width="800" height="91"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Por qué importa esto?&lt;/strong&gt; Porque optimiza el espacio. Si tienes 10 proyectos usando la misma librería, solo se descarga una vez en tu disco duro.&lt;/p&gt;

&lt;h2&gt;
  
  
  La jerarquía de configuración
&lt;/h2&gt;

&lt;p&gt;Antes de escribir una sola línea de configuración, debes entender cómo "piensa" NuGet. Cuando ejecutas un restore, no solo mira tu proyecto. NuGet combina configuraciones en cascada siguiendo una jerarquía estricta:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nivel Máquina:&lt;/strong&gt; A menudo este archivo ni siquiera existe físicamente o está vacío, a menos que un administrador de sistemas lo haya puesto ahí.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nivel Usuario:&lt;/strong&gt; Este es el más común (&lt;code&gt;%appdata%\NuGet\NuGet.Config&lt;/code&gt;) y suele acumular mucha &lt;em&gt;"basura digital"&lt;/em&gt; con el tiempo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nivel Directorio (Recursivo):&lt;/strong&gt; ¡Aquí está la trampa! NuGet busca en la carpeta de tu solución... pero si no encuentra lo que busca, sube a la carpeta padre, y luego a la del abuelo, hasta llegar a la raíz del disco.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  El origen del "En mi máquina funciona" 🤷‍♂️
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3dajrvpxpyf4m7z85tp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3dajrvpxpyf4m7z85tp.png" alt="Meme: It works on my machine" width="600" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aquí nace el famoso meme. Imagina que tú tienes configurado un feed privado en tu Nivel Usuario porque trabajas en varios proyectos de la empresa. Creas un proyecto nuevo y compila perfecto. Tu compañero clona el repositorio, intenta compilar y... error.&lt;/p&gt;

&lt;p&gt;¿Por qué? Porque tu proyecto está dependiendo de una configuración "invisible" que vive solo en tu usuario. Para tu compañero, ese feed no existe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cómo detecto esto?&lt;/strong&gt; No adivines. Sitúate en la carpeta de tu solución y ejecuta el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet nuget list &lt;span class="nb"&gt;source&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando te mostrará la lista final y combinada de todos los orígenes que NuGet está usando realmente en esa carpeta. Si ves rutas que no reconoces o servidores apagados, es culpa de la herencia.&lt;/p&gt;

&lt;h2&gt;
  
  
  NuGet.config
&lt;/h2&gt;

&lt;p&gt;¿Cómo rompemos esa cadena de herencia tóxica y arreglamos el proyecto para todos? Creando un archivo NuGet.config explícito en la raíz de tu solución.&lt;/p&gt;

&lt;p&gt;Aquí tienes una configuración que cubre los escenarios reales:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;packageSources&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- ¡IMPORTANTE! &amp;lt;clear/&amp;gt; elimina toda la "basura" heredada del usuario o máquina --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;clear&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- 1. El estándar público --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"nuget.org"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"https://api.nuget.org/v3/index.json"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- 2. Nube Privada (GitHub Packages, Azure, AWS) --&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Ideal para equipos modernos y CI/CD --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"GitHubFeed"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"https://nuget.pkg.github.com/mi-empresa/index.json"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- 3. Servidor NuGet Local (BaGet o similar) --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"BadGetFeed"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"http://servidor-interno:5555/v3/index.json"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- 4. Carpeta Local en Servidor On-Premise --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"OnPremiseFeed"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"./LibreriasAntiguas"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/packageSources&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Puedes deshabilitar fuentes temporalmente sin borrar la línea --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;disabledPackageSources&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"OnPremiseFeed"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/disabledPackageSources&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;packageSourceCredentials&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Autenticación Segura para feeds privados (Usa variables de entorno) --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;GitHubFeed&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"Username"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"DevUser"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;add&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"ClearTextPassword"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"%GITHUB_TOKEN%"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/GitHubFeed&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/packageSourceCredentials&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beneficios de configurar esto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🛡 &lt;strong&gt;Aislamiento:&lt;/strong&gt; Con &lt;code&gt;&amp;lt;clear /&amp;gt;&lt;/code&gt;, proteges tu proyecto de configuraciones globales rotas.&lt;/li&gt;
&lt;li&gt;🛠 &lt;strong&gt;Independencia:&lt;/strong&gt; Si un dev nuevo entra, solo hace &lt;code&gt;git clone&lt;/code&gt; y &lt;code&gt;dotnet restore&lt;/code&gt;. No necesita configurar nada manual.&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;CI/CD Friendly:&lt;/strong&gt; Tus Pipelines sabrán exactamente dónde buscar sin pasos extraños.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  El caos de la prioridad
&lt;/h2&gt;

&lt;p&gt;Aquí es donde muchos desarrolladores fallan. Si tienes configurado &lt;code&gt;nuget.org&lt;/code&gt; y &lt;code&gt;GitHubFeed&lt;/code&gt;, y ambos tienen un package llamado &lt;code&gt;Newtonsoft.Json&lt;/code&gt;... ¿cuál se descarga?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3uhl4ch5ohckrow8sr9i.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3uhl4ch5ohckrow8sr9i.jpg" alt="Meme Spiderman señalándose: Conflicto de nombres de paquetes" width="150" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NuGet actua "al primero que responda". Esto es peligroso por dos razones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rendimiento:&lt;/strong&gt; NuGet pierde tiempo buscando tu package privado en la tienda pública.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seguridad:&lt;/strong&gt; Si un atacante sube un paquete malicioso a &lt;code&gt;nuget.org&lt;/code&gt; con el mismo nombre que tu paquete privado interno (ej: &lt;code&gt;MiBanco.Core&lt;/code&gt;), ¡tu proyecto podría descargar el package del atacante sin darte cuenta! 🚨&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8qxbjeyxkofav7anfnkm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8qxbjeyxkofav7anfnkm.png" alt="Diagrama de amenaza: Dependency Confusion" width="800" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para solucionar el caos de prioridad y asegurar qué bajamos, tenemos dos herramientas clave:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Package Source Mapping
&lt;/h3&gt;

&lt;p&gt;Es básicamente decirle a NuGet: &lt;em&gt;"Los paquetes de Microsoft búscalos en la tienda pública, y los paquetes de mi empresa SOLO búscalos en mis servidores".&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- ... sección packageSources definida arriba ... --&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- AQUÍ ESTÁ LA MAGIA --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;packageSourceMapping&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Regla 1: Mis librerías Core van a GitHub Packages --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;packageSource&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"GitHubFeed"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;package&lt;/span&gt; &lt;span class="na"&gt;pattern=&lt;/span&gt;&lt;span class="s"&gt;"MyCompany.Core.*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;package&lt;/span&gt; &lt;span class="na"&gt;pattern=&lt;/span&gt;&lt;span class="s"&gt;"MyCompany.Auth.*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/packageSource&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Regla 2: Librerías internas van al Server NuGet Privado --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;packageSource&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"BadGetFeed"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;package&lt;/span&gt; &lt;span class="na"&gt;pattern=&lt;/span&gt;&lt;span class="s"&gt;"InternalTools.*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/packageSource&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Regla 3: Componentes viejos van a la carpeta local --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;packageSource&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"OnPremiseFeed"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;package&lt;/span&gt; &lt;span class="na"&gt;pattern=&lt;/span&gt;&lt;span class="s"&gt;"OldComponent.WinForms.*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/packageSource&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Regla 4: Todo lo demás (Microsoft, System, etc.), búscalo en nuget.org --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;packageSource&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"nuget.org"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;package&lt;/span&gt; &lt;span class="na"&gt;pattern=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/packageSource&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/packageSourceMapping&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Auditoría de vulnerabilidades
&lt;/h3&gt;

&lt;p&gt;A veces descargas el paquete correcto, pero tiene agujeros de seguridad conocidos. No necesitas herramientas caras; .NET lo trae nativo.&lt;br&gt;
Ejecuta esto regularmente o en tu CI/CD:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet list package &lt;span class="nt"&gt;--vulnerable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Te dirá qué paquetes tienen riesgos (Crítico, alto o moderado) y a qué versión segura actualizar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Central Package Management (CPM)
&lt;/h2&gt;

&lt;p&gt;Si trabajas en una solución con muchos servicios, seguro te ha pasado esto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El Proyecto A usa &lt;code&gt;Newtonsoft.Json&lt;/code&gt; v11.&lt;/li&gt;
&lt;li&gt;El Proyecto B usa &lt;code&gt;Newtonsoft.Json&lt;/code&gt; v13.&lt;/li&gt;
&lt;li&gt;El Proyecto C usa &lt;code&gt;Newtonsoft.Json&lt;/code&gt; v9.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;¡Es un caos de versiones! 🤯&lt;/p&gt;

&lt;p&gt;Para solucionar esto en proyectos modernos, usamos Central Package Management (CPM). En lugar de definir la versión en cada .csproj, las centralizamos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F70i7sme6fj14u35knhlp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F70i7sme6fj14u35knhlp.png" alt="Comparativa: Caos de versiones vs Central Package Management" width="800" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Paso 1: Crear archivo Directory.Packages.props en la raíz
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Project&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Activar CPM --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ManagePackageVersionsCentrally&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/ManagePackageVersionsCentrally&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ItemGroup&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Aquí defines la versión UNA SOLA VEZ para toda la solución --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageVersion&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Newtonsoft.Json"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"13.0.3"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageVersion&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.EntityFrameworkCore"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"8.0.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Paso 2: Limpiar tus .csproj
&lt;/h3&gt;

&lt;p&gt;En tus proyectos individuales, ya no pones la versión, solo el nombre:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- En .csproj --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ItemGroup&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- Sin versión porque ya lo toma de Directory.Packages.props --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Newtonsoft.Json"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ¿Cómo aplico los cambios?
&lt;/h2&gt;

&lt;p&gt;Una vez que has creado o ajustado tu archivo NuGet.config con los sources y el mapping, ve a tu terminal y ejecuta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Limpia cachés locales para asegurar que las reglas nuevas apliquen&lt;/span&gt;
dotnet nuget locals all &lt;span class="nt"&gt;--clear&lt;/span&gt;

&lt;span class="c"&gt;# Restaura usando la nueva configuración&lt;/span&gt;
dotnet restore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ¿Por qué deberías dominar esto?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Resurrección de Proyectos:&lt;/strong&gt; Puedes levantar proyectos Legacy en minutos mapeando los source que corresponde.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seguridad Empresarial:&lt;/strong&gt; Proteges a tu organización de ataques de cadena de suministro y vulnerabilidades conocidas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arquitectura Limpia:&lt;/strong&gt; Con CPM, mantienes tus dependencias ordenadas y actualizadas sin esfuerzo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No dejes que las dependencias te controlen a ti. ¡Toma el control de tus paquetes!&lt;/p&gt;

&lt;p&gt;¡Happy coding! 🚀&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>dotnet</category>
      <category>nuget</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Git Merge vs Git Rebase: Cómo tener un historial ordenado y claro</title>
      <dc:creator>Manuel Dávila Alarcón</dc:creator>
      <pubDate>Fri, 07 Feb 2025 05:51:39 +0000</pubDate>
      <link>https://dev.to/maadcode/git-merge-vs-git-rebase-como-tener-un-historial-ordenado-y-claro-2kic</link>
      <guid>https://dev.to/maadcode/git-merge-vs-git-rebase-como-tener-un-historial-ordenado-y-claro-2kic</guid>
      <description>&lt;p&gt;Si trabajas en equipo con Git, seguramente has escuchado sobre &lt;code&gt;git merge&lt;/code&gt; y &lt;code&gt;git rebase&lt;/code&gt;. Ambos sirven para combinar ramas, pero tienen efectos diferentes en la historia del repositorio. Usarlos correctamente puede hacer que tu historial de Git sea fácil de entender 🤩 o un desastre incomprensible 😵.&lt;/p&gt;

&lt;p&gt;Vamos a ver en detalle en qué se diferencian y cuándo usar cada uno.&lt;/p&gt;

&lt;h2&gt;
  
  
  Git Merge
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📌 ¿Qué hace Git Merge y por qué es útil??
&lt;/h3&gt;

&lt;p&gt;Cuando usas &lt;code&gt;git merge&lt;/code&gt;, Git toma dos ramas y las combina en una nueva confirmación (&lt;strong&gt;commit&lt;/strong&gt;), manteniendo el historial de ambas ramas intacto. Se usa mucho cuando integras una rama secundaria en la principal (como &lt;code&gt;develop&lt;/code&gt; o &lt;code&gt;main&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Imagina que tienes dos caminos separados que finalmente se juntan en una carretera principal. Sigues viendo de dónde viene cada uno, pero ahora forman parte de la misma ruta.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnzdcgvotqmtf3m7toy7m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnzdcgvotqmtf3m7toy7m.jpg" alt=" " width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  🛠️ Cómo usar Git Merge y cómo se ve en los gráficos
&lt;/h3&gt;

&lt;p&gt;Para aplicar merge a una rama llamada &lt;code&gt;develop&lt;/code&gt;, es decir queremos enviar los cambios de &lt;code&gt;feature/chatbot&lt;/code&gt; hacia &lt;code&gt;develop&lt;/code&gt;. Primero debes posicionarte en la rama &lt;code&gt;develop&lt;/code&gt; y ejecutar el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout develop
git merge feature/chatbot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto genera un commit de &lt;strong&gt;merge&lt;/strong&gt; en &lt;code&gt;develop&lt;/code&gt; con todo el historial de &lt;code&gt;feature/chatbot&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Cómo debería verse un merge en el gráfico de historial de git.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fewfdp0a01k44tjiytt2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fewfdp0a01k44tjiytt2g.png" alt=" " width="564" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como puedes ver, hay una evidencia clara de que el branch &lt;code&gt;feature/chatbot&lt;/code&gt; se incorporó en &lt;code&gt;develop&lt;/code&gt;, lo hace muy fácil de leer.&lt;/p&gt;

&lt;p&gt;En este caso no hubo conflictos. Sin embargo, sabemos que en un entorno productivo, el caos predomina 🔥, así que veamos un escenario más conflictivo.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 Caso real: Cuándo usar Git Merge
&lt;/h3&gt;

&lt;p&gt;Imagina que trabajas en un equipo desarrollando una nueva funcionalidad en una rama llamada &lt;code&gt;feature/chatbot&lt;/code&gt;. Mientras tanto, otros compañeros han seguido trabajando en &lt;code&gt;develop&lt;/code&gt;, agregando nuevas mejoras y correcciones de errores.&lt;/p&gt;

&lt;p&gt;Llega el momento de integrar &lt;code&gt;feature/chatbot&lt;/code&gt; en &lt;code&gt;develop&lt;/code&gt;, pero quieres asegurarte de que el historial refleje claramente que esta funcionalidad se desarrolló en paralelo y luego se unió a la rama principal. Aquí es donde &lt;code&gt;git merge&lt;/code&gt; brilla.&lt;/p&gt;

&lt;p&gt;Se creará un commit de merge que preservará todo el historial de &lt;code&gt;feature/chatbot&lt;/code&gt;, dejando claro cuándo y cómo se unieron los cambios. Esto es útil en proyectos colaborativos porque facilita el rastreo de la evolución del código y evita sobrescribir accidentalmente cambios de otros.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7wtpdsqfdo2mk7utqeni.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7wtpdsqfdo2mk7utqeni.png" alt=" " width="611" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sin embargo, dado que &lt;code&gt;develop&lt;/code&gt; ha seguido evolucionando con cambios que no están en &lt;code&gt;feature/chatbot&lt;/code&gt;, es probable que debas resolver conflictos de merge. Esto sucede porque algunos archivos pueden haber sido modificados en ambas ramas, y Git no sabe cuál versión debería mantenerse. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpot887c2xa5w2qd3qrp3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpot887c2xa5w2qd3qrp3.png" alt=" " width="748" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La solución consiste en revisar y seleccionar manualmente los cambios adecuados antes de finalizar el merge.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xl5plm18cp88ewbbru7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xl5plm18cp88ewbbru7.png" alt=" " width="609" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una vez que solucionas los conflictos entre 2 ramas, el mismo conflicto no debería volver a aparecer (a menos que haya nuevas modificaciones en el archivo o clase que otro desarrollador ha modificado). Incluso si agregas un nuevo commit a &lt;code&gt;feature/chatbot&lt;/code&gt; y vuelves aplicar merger hacia &lt;code&gt;develop&lt;/code&gt; nuevamente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9gdu5ierdob63ejyfrs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9gdu5ierdob63ejyfrs.png" alt=" " width="629" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si en lugar de &lt;code&gt;git merge&lt;/code&gt; intentáramos un &lt;code&gt;git rebase&lt;/code&gt;, estaríamos reescribiendo la historia de &lt;code&gt;feature/chatbot&lt;/code&gt; como si siempre hubiera estado basada en la última versión de &lt;code&gt;develop&lt;/code&gt;. Esto podría generar problemas si otros colaboradores ya han trabajado sobre la misma rama y necesitan un historial claro de integración.&lt;/p&gt;

&lt;p&gt;Por eso, &lt;code&gt;git merge&lt;/code&gt; es la mejor opción aquí, ya que mantiene un historial fiel del desarrollo de la funcionalidad y facilita la colaboración en equipo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Para los ejemplos del gráfico del historial de Git utilizo &lt;a href="https://www.gitkraken.com/" rel="noopener noreferrer"&gt;GitKraken Desktop&lt;/a&gt;, pero en cualquier cliente de Git deberías poder visualizarlo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Git Rebase
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📌 ¿Qué hace Git Rebase y por qué es útil??
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;git rebase&lt;/code&gt; toma los commits de una rama y los aplica sobre otra como si siempre hubieran estado allí. En lugar de mezclar con un commit de merge, reescribe la historia para que los cambios parezcan hechos directamente sobre la rama principal.&lt;/p&gt;

&lt;p&gt;Es como si, en lugar de recordar que tomaste un desvío en el camino, tu GPS reescribiera el trayecto para que pareciera que nunca te desviaste.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5tbeshox8e6mzwxoydq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5tbeshox8e6mzwxoydq.jpg" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;También se podría usar para no dejar evidencia de cambios que vienen de una rama específica 👀 aparecen los commits pero no la rama del que vienen.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  🛠️ Cómo usar Git Rebase y cómo se ve en los gráficos?
&lt;/h3&gt;

&lt;p&gt;Para aplicar rebase a una rama llamada &lt;code&gt;feature/oauth-gmail&lt;/code&gt;, la cual se creó anteriormente a partir de &lt;code&gt;main&lt;/code&gt;. Primero debes posicionarte sobre la rama &lt;code&gt;feature/oauth-gmail&lt;/code&gt; y ejecutar el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout feature/oauth-gmail
git rebase main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;También podrías hacerlo desde un cliente de Git como Fork, Git Kraken u otro, presionando clic derecho a la rama que quieres aplicar rebase (como main) y seleccionar "rebase".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rp4h4on4yknjkc5x2n0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rp4h4on4yknjkc5x2n0.png" alt=" " width="613" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esto generará que la rama &lt;code&gt;feature/oauth-gmail&lt;/code&gt; se alinee con la rama &lt;code&gt;main&lt;/code&gt; como si se hubiera creado con la ultima versión de &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Cómo debería verse un rebase en el gráfico de historial de git.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzspf8vc0ar9dqqnpcn21.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzspf8vc0ar9dqqnpcn21.png" alt=" " width="626" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 Caso real: Cuándo usar Git Rebase
&lt;/h3&gt;

&lt;p&gt;Imagina que estás trabajando en una nueva funcionalidad en una rama &lt;code&gt;feature/oauth-gmail&lt;/code&gt;, la cual creaste a partir de &lt;code&gt;master&lt;/code&gt;. Mientras tanto, &lt;code&gt;master&lt;/code&gt; ha recibido múltiples actualizaciones, incluyendo hotfixes y nuevos releases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fna51q2ediqte2f6hrjqb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fna51q2ediqte2f6hrjqb.png" alt=" " width="602" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dado que &lt;code&gt;feature/oauth-gmail&lt;/code&gt; proviene de &lt;code&gt;master&lt;/code&gt;, lo ideal es hacer un &lt;code&gt;git rebase master&lt;/code&gt; para alinear la rama con los cambios más recientes sin introducir un commit de merge innecesario. &lt;/p&gt;

&lt;p&gt;Si en su lugar usaras &lt;code&gt;git merge&lt;/code&gt;, se generaría una mezcla bidireccional entre &lt;code&gt;master&lt;/code&gt; y &lt;code&gt;feature/oauth-gmail&lt;/code&gt;, lo que haría más confusa la lectura del historial y rompería con la estrategia de branching.&lt;/p&gt;

&lt;p&gt;Veamos como quedaría si queremos integrar con merge y luego queremos hacer un commit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Favtr2u4th0fcftcz9lyy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Favtr2u4th0fcftcz9lyy.png" alt=" " width="605" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como puedes ver, la rama master deja de tener un historial limpio 😖&lt;/p&gt;

&lt;p&gt;Con &lt;code&gt;git rebase master&lt;/code&gt;, los commits de &lt;code&gt;feature/oauth-gmail&lt;/code&gt; se reordenan y aplican sobre la última versión de &lt;code&gt;master&lt;/code&gt;, manteniendo un historial más limpio y lineal. Esto facilita la revisión del código y evita la complejidad innecesaria en el historial del proyecto.&lt;/p&gt;

&lt;p&gt;Si hay conflictos, deberás resolverlos manualmente en cada paso del rebase, pero al final obtendrás una estructura más clara y organizada.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff9jx3a5oh3y5048qhkhr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff9jx3a5oh3y5048qhkhr.png" alt=" " width="589" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Incluso si quisiéramos hacer un nuevo commit quedaría más limpio tanto el historial de commits del feature como master.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xfj9gbflt2r3nv55w2l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xfj9gbflt2r3nv55w2l.png" alt=" " width="593" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tanto con Git Merge como Git Rebase, no te salvarás de solucionar conflictos de merge. El propósito de estos comandos es mantener un historial de git de la forma más óptima para los desarrolladores y no tiene que ver con la forma de manejar los conflictos de merge.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🎉 Conclusión
&lt;/h2&gt;

&lt;p&gt;Usa merge para integrar ramas de larga duración (como features hacia develop en Git Flow). Usa rebase para mantener actualizadas tus feature branches antes de mergearlas.&lt;/p&gt;

&lt;p&gt;Tanto &lt;code&gt;git merge&lt;/code&gt; como &lt;code&gt;git rebase&lt;/code&gt; son herramientas poderosas y necesarias. No hay una "mejor" que otra, sino que cada una se adapta a diferentes situaciones. Si quieres un historial claro y ordenado, usa rebase. Si necesitas contexto y claridad en las integraciones, opta por merge.&lt;br&gt;
Es importante que todo el equipo siga las mismas prácticas para mantener un historial de Git consistente.&lt;/p&gt;

&lt;p&gt;¡Ahora sí, a escribir código y a hacer commits con confianza! 🚀&lt;/p&gt;

</description>
      <category>programming</category>
      <category>git</category>
      <category>spanish</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Cómo gestionar tus proyectos de software con Github</title>
      <dc:creator>Manuel Dávila Alarcón</dc:creator>
      <pubDate>Wed, 15 Jan 2025 14:54:16 +0000</pubDate>
      <link>https://dev.to/maadcode/como-gestionar-tus-proyectos-de-software-con-github-4elj</link>
      <guid>https://dev.to/maadcode/como-gestionar-tus-proyectos-de-software-con-github-4elj</guid>
      <description>&lt;p&gt;¿Estás comenzando un proyecto de software y no sabes dónde gestionarlo? Hoy quiero contarte por qué GitHub puede ser tu mejor aliado. Aunque existen herramientas increíbles como GitLab o Bitbucket para repositorios de código, Jira o Trello para tareas, y Confluence o Notion para documentar, GitHub te ofrece un &lt;strong&gt;combo completo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;En este artículo, exploraremos cómo aprovechar GitHub al máximo, desde la gestión de tareas hasta la automatización de procesos. Si buscas una solución integral para gestionar tus proyectos de software, ¡estás en el lugar correcto! 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es GitHub y qué lo hace especial?
&lt;/h2&gt;

&lt;p&gt;GitHub es mucho más que una plataforma para almacenar código. Es un ecosistema donde puedes controlar versiones, colaborar con equipos, gestionar tareas y mucho más. Pero antes de avanzar, aclaremos algo fundamental:&lt;br&gt;
&lt;strong&gt;¿Git o GitHub?&lt;/strong&gt;&lt;br&gt;
👁️‍🗨️ Aunque suenen similares, son diferentes. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git: Es un sistema de control de versiones que permite rastrear cambios en tu código.&lt;/li&gt;
&lt;li&gt;GitHub: Es una plataforma basada en la nube que utiliza Git para facilitar el trabajo colaborativo.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Si no estás familiarizado con Git, te recomiendo la &lt;a href="https://learn.microsoft.com/es-es/training/paths/intro-to-vc-git/" rel="noopener noreferrer"&gt;la ruta de aprendizaje de Git en Microsoft Learn&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ¿Por qué usar GitHub?
&lt;/h2&gt;

&lt;p&gt;GitHub no se limita a almacenar código; ofrece herramientas avanzadas que te permiten gestionar proyectos de principio a fin. Algunas de sus funcionalidades clave incluyen:&lt;br&gt;
✔️&lt;strong&gt;Issues&lt;/strong&gt;: Una forma estructurada de registrar problemas, tareas o ideas.&lt;br&gt;
✔️&lt;strong&gt;Pull Request&lt;/strong&gt;: Para colaborar en el código, revisarlo y discutir cambios antes de integrarlos.&lt;br&gt;
✔️&lt;strong&gt;Colaboradores y equipos&lt;/strong&gt;: Gestiona quién tiene acceso a tu proyecto y qué permisos tienen.&lt;br&gt;
✔️&lt;strong&gt;Github Projects&lt;/strong&gt;: Tableros tipo Kanban u otro tipo de plantilla para organizar tareas y planificar proyectos.&lt;br&gt;
✔️&lt;strong&gt;Github Wiki&lt;/strong&gt;: Documentación centralizada para tu equipo.&lt;br&gt;
✔️&lt;strong&gt;Github Copilot&lt;/strong&gt;: Tu asistente de IA Generativa para escribir código más rápido.&lt;br&gt;
✔️&lt;strong&gt;Github Actions&lt;/strong&gt;: Automatiza procesos como pruebas, despliegues y mucho más.&lt;br&gt;
✔️&lt;strong&gt;Github Codespaces&lt;/strong&gt;: Entornos de desarrollo en la nube.&lt;br&gt;
✔️&lt;strong&gt;Github Pages&lt;/strong&gt;: Hospeda sitios web estáticos directamente desde tu repositorio.&lt;br&gt;
✔️&lt;strong&gt;Code Security&lt;/strong&gt;: Herramientas para proteger tu código.&lt;br&gt;
✔️&lt;strong&gt;Marketplace&lt;/strong&gt;: Encuentra extensiones que potencien tu flujo de trabajo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caso práctico: Gestión de un proyecto de red social
&lt;/h2&gt;

&lt;p&gt;Imagina que estás desarrollando una red social en .NET con un equipo. Cada persona está encargada de una funcionalidad: autenticación, perfiles de usuario, publicaciones y notificaciones. A continuación, te muestro cómo usar GitHub en cada etapa del proyecto.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Crear el repositorio base
&lt;/h3&gt;

&lt;p&gt;Lo primero es crear un repositorio para centralizar todo tu código y configurarlo.&lt;/p&gt;

&lt;p&gt;Pasos básicos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inicia sesión en GitHub.&lt;/li&gt;
&lt;li&gt;Haz clic en "New Repository".&lt;/li&gt;
&lt;li&gt;Completa los campos (nombre del repositorio, descripción, visibilidad).&lt;/li&gt;
&lt;li&gt;Agrega un .gitignore y una licencia, si es necesario.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiucbhr0x5ndpnr2xfcxy.png" alt="Captura de la creación de un repositorio en Github" width="541" height="327"&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft50rwtk9hrbostuquzk0.png" alt="Captura de la configuración de gitignore, README y licencia del repositorio en Github" width="800" height="660"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2. Agregar colaboradores y equipos 👨‍💻👩‍💻
&lt;/h3&gt;

&lt;p&gt;Agregar colaboradores en GitHub es como organizar una fiesta: tú eres el anfitrión, y los colaboradores son los invitados que pueden ayudar a decorar, traer comida (o en este caso, código).&lt;/p&gt;

&lt;p&gt;Puedes agregar a cada miembro del equipo con permisos específicos. Por ejemplo, el líder del proyecto podría tener permisos de administrador, mientras que los desarrolladores solo pueden enviar código y revisarlo.&lt;/p&gt;

&lt;p&gt;Pasos para agregar un colaborador:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ve a la página principal de tu repositorio en GitHub.&lt;/li&gt;
&lt;li&gt;Haz clic en la pestaña "Settings" (configuración).&lt;/li&gt;
&lt;li&gt;Busca la sección "Collaborators and Teams" y haz clic.&lt;/li&gt;
&lt;li&gt;En "Add Collaborator", escribe el nombre de usuario o correo electrónico de la persona.&lt;/li&gt;
&lt;li&gt;La persona recibirá una invitación y, al aceptarla, ya será parte del proyecto.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foufkvn20nq97zaomm88j.PNG" alt=" " width="800" height="465"&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh0igwtc2iry2urzx45sy.PNG" alt=" " width="800" height="568"&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7y0uw83d9fpa1cfbanv.PNG" alt=" " width="800" height="438"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Si tu proyecto es Open Source, puedes recibir contribuciones mediante pull request de terceros sin tener que agregarlos como colaborador.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3. Organizar tareas con Issues y Projects
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Projects: Usa un tablero tipo Kanban con columnas como "Por hacer", "En progreso" y "Completado" para mover tareas según su estado.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3lng3l8tzwlf7zlpg4aa.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3lng3l8tzwlf7zlpg4aa.PNG" alt=" " width="800" height="307"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6g6jh3jkbzn6zsr840d.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6g6jh3jkbzn6zsr840d.PNG" alt=" " width="800" height="472"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fikewcuf52xzauze3re5z.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fikewcuf52xzauze3re5z.PNG" alt=" " width="800" height="440"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzb1eyordme6ab0ww5ct7.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzb1eyordme6ab0ww5ct7.PNG" alt=" " width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Issues: Define tareas como "Agregar autenticación con OAuth2" o "Implementar Endpoint Publicaciones". Cada issue tiene un responsable, una prioridad y una fecha límite.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjbk9mmcf8kpjdvn6newg.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjbk9mmcf8kpjdvn6newg.PNG" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh6zvofnx31ngx3kot9nl.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh6zvofnx31ngx3kot9nl.PNG" alt=" " width="800" height="423"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F690oiw5v48gkvstxuacn.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F690oiw5v48gkvstxuacn.PNG" alt=" " width="800" height="384"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbycxi4cbv2c1h9lupt6t.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbycxi4cbv2c1h9lupt6t.PNG" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff7p1g76cghlugk5f3oja.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff7p1g76cghlugk5f3oja.PNG" alt=" " width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Crear, revisar y aprobar cambios con Pull Requests 🔎
&lt;/h3&gt;

&lt;p&gt;Cuando alguien del equipo desarrolla una funcionalidad, como "Publicaciones", crea una rama (feature/posts) y abre un Pull Request (PR) para que el resto del equipo revise el código.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Famjwo6htaq9hmbjdrjyt.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Famjwo6htaq9hmbjdrjyt.PNG" alt=" " width="800" height="336"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffrlk573e9h17db5cd4kd.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffrlk573e9h17db5cd4kd.PNG" alt=" " width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Los revisores pueden comentar, sugerir cambios, y asegurarse de que todo esté en orden antes de integrar el código.&lt;/p&gt;

&lt;p&gt;Si todo esta bien, podemos aprobar el cambio e integrarlo a rama que solicitaron en el pull request.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxlkphsiy10l5f5ezu3gq.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxlkphsiy10l5f5ezu3gq.PNG" alt=" " width="800" height="476"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdat27086878cpwlfe07v.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdat27086878cpwlfe07v.PNG" alt=" " width="800" height="740"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgr22lpjkigxuqtpp9vx1.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgr22lpjkigxuqtpp9vx1.PNG" alt=" " width="800" height="217"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm83zrbd5brisa7t9oj0k.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm83zrbd5brisa7t9oj0k.PNG" alt=" " width="800" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Documentar con GitHub Wiki 📝
&lt;/h3&gt;

&lt;p&gt;La documentación es clave para evitar confusiones. En GitHub Wiki puedes incluir:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arquitectura del sistema: Cómo se conecta cada módulo.&lt;/li&gt;
&lt;li&gt;Guía de instalación: Instrucciones para configurar el entorno.&lt;/li&gt;
&lt;li&gt;Dependencias: Herramientas y librerías utilizadas.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdbe5bt1592axkmx7jb07.png" alt=" " width="800" height="372"&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsg4vgmtsdw1lpvlmpb26.png" alt=" " width="800" height="442"&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fifp5clftdfcm193gsckl.png" alt=" " width="800" height="309"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Es probable que hacer la documentación te cause aburrimiento pero no tenerlo te causará pesadillas. 😖&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  6. Acelerar el desarrollo con GitHub Copilot 🤖
&lt;/h3&gt;

&lt;p&gt;Escribir código repetitivo puede ser frustrante. Con GitHub Copilot, puedes generar lógica automáticamente. Por ejemplo, al implementar notificaciones, Copilot puede sugerir código para manejar excepciones o enviar correos.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwt6ik8x2aky5eoa624h4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwt6ik8x2aky5eoa624h4.png" alt=" " width="800" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;GitHub Copilot ahora tiene un plan gratuito que puedes usar desde editores como Visual Studio Code, Visual Studio o JetBrains. Más detalles &lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  7. Automatizar con GitHub Actions ⚙️
&lt;/h3&gt;

&lt;p&gt;GitHub Actions permite automatizar flujos de trabajo. Algunos ejemplos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ejecutar pruebas unitarias al crear un PR.&lt;/li&gt;
&lt;li&gt;Desplegar la aplicación en Azure tras pasar las pruebas.&lt;/li&gt;
&lt;li&gt;Enviar notificaciones de estado al equipo vía Slack.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7w46srgq6d3mwmrdixgu.png" alt=" " width="800" height="340"&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr1j79r6ufe4fp79hvn3t.png" alt=" " width="800" height="547"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  8. Trabajar desde cualquier lugar con Github Codespaces 🖥️
&lt;/h3&gt;

&lt;p&gt;¿Necesitas trabajar desde un dispositivo donde no tienes configurado el entorno? GitHub Codespaces te ofrece un entorno de desarrollo virtual listo para usar desde tu navegador.&lt;/p&gt;

&lt;p&gt;En caso de que alguien del equipo necesite contribuir rápidamente pero no tiene el entorno configurado, puede abrir un Codespace.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3p9a9ozn7x1yzs4b4uir.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3p9a9ozn7x1yzs4b4uir.PNG" alt=" " width="800" height="401"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyh2gacnx05uz1ltc9a3x.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyh2gacnx05uz1ltc9a3x.PNG" alt=" " width="800" height="416"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsjfcl9b5zgbag5nav5z0.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsjfcl9b5zgbag5nav5z0.PNG" alt=" " width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Recuerda detener o eliminar tu codespace para evitar consumo innecesario de recursos, ya que hay un límite mensual que pueden utilizar gratuitamente. Puedes ver tu consumo de recursos &lt;a href="https://github.com/settings/billing/summary" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  9. Publicar documentación o prototipos con Github Pages
&lt;/h3&gt;

&lt;p&gt;Cuando tu proyecto esté listo o necesites compartir documentación o prototipos con clientes, GitHub Pages es una solución ideal para alojar sitios web estáticos. Puedes usarlo para:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Documentación del proyecto: Crear una página atractiva para tu Wiki con Markdown o un generador como Jekyll.&lt;/li&gt;
&lt;li&gt;Demostraciones de prototipos: Publicar una versión básica de tu red social para que los stakeholders puedan visualizarla.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Supongamos que has creado una versión mínima de tu red social con una interfaz básica. Podrías usar GitHub Pages para desplegar esta demo. Solo necesitas guardar los archivos HTML, CSS y JavaScript y habilitar la opción en la configuración del repositorio.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qsaod0c5sjwojvrfazu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qsaod0c5sjwojvrfazu.png" alt=" " width="800" height="430"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffpe9p5rcy4b6wk6wgqsd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffpe9p5rcy4b6wk6wgqsd.png" alt=" " width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Con Github Pages incluso podrías personalizar con un dominio propio como &lt;a href="http://www.example.com" rel="noopener noreferrer"&gt;www.example.com&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  10. Proteger tu código con GitHub Code Security 🔒
&lt;/h3&gt;

&lt;p&gt;GitHub ofrece herramientas integradas para mantener tu proyecto seguro y evitar vulnerabilidades. Algunas de las funciones más destacadas son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Escaneo de código: Analiza tu repositorio en busca de vulnerabilidades en librerías o errores de seguridad en tu código.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dependabot Alerts: Detecta dependencias obsoletas o con problemas y sugiere actualizaciones automáticas.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgaen66dty01ofo5gl1le.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgaen66dty01ofo5gl1le.png" alt=" " width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Protección de ramas: Configura restricciones en la rama principal para evitar que se integre código sin revisión.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzqk4ac4ec9q54eb2xpq5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzqk4ac4ec9q54eb2xpq5.png" alt=" " width="800" height="530"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fut4xeh9x3h7hwcy8yigg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fut4xeh9x3h7hwcy8yigg.png" alt=" " width="800" height="746"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Es probable que algunas funciones no esten habilitadas para repositorios privados o de organizaciones.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  11. Aprovecha Github Marketplace 🛒
&lt;/h3&gt;

&lt;p&gt;GitHub Marketplace es un repositorio de herramientas y aplicaciones que puedes integrar fácilmente a tu proyecto. Desde CI/CD hasta análisis de código, modelos de IA y extensiones para Copilot, y bots para gestionar tareas, tienes múltiples opciones para mejorar tu productividad. &lt;/p&gt;

&lt;p&gt;Por ejemplo, puedes instalar un Action para desplegar automáticamente tu aplicación en Docker Hub.&lt;/p&gt;

&lt;p&gt;Herramientas adicionales de Marketplace que puedes explorar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ZenHub: Para extender la funcionalidad de Projects con diagramas de Gantt.&lt;/li&gt;
&lt;li&gt;Snyk: Para análisis avanzado de vulnerabilidades.&lt;/li&gt;
&lt;li&gt;CodeClimate: Para medir la calidad del código.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm7p3a2cb2suh34nggetg.png" alt=" " width="793" height="678"&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbv9ed0pll4k33gwf2z5o.png" alt=" " width="800" height="577"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Dedica tiempo a explorar Marketplace, ya que muchas de estas herramientas son gratuitas o tienen planes básicos perfectos para empezar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Beneficios de usar GitHub para tus proyectos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Centralización: Todo (código, tareas, documentación) en un solo lugar.&lt;/li&gt;
&lt;li&gt;Colaboración: Facilita el trabajo en equipo con herramientas intuitivas.&lt;/li&gt;
&lt;li&gt;Escalabilidad: Desde proyectos pequeños hasta sistemas empresariales complejos.&lt;/li&gt;
&lt;li&gt;Automatización: Ahorras tiempo en tareas repetitivas.&lt;/li&gt;
&lt;li&gt;Flexibilidad: Adapta las herramientas a tus necesidades.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ¡Atrévete a explorar GitHub!
&lt;/h2&gt;

&lt;p&gt;GitHub no es solo para almacenar código; es una herramienta integral que puede transformar cómo gestionas tus proyectos. Si estás buscando optimizar tu flujo de trabajo y trabajar de manera más eficiente, empieza hoy mismo.&lt;/p&gt;

&lt;p&gt;GitHub tiene una gran comunidad y puedes encontrar recursos de aprendizaje, participar en proyectos Open Source o integrar GitHub con tus propias aplicaciones usando su API.&lt;/p&gt;

&lt;p&gt;¡Manos a la obra! Crea tu primer repositorio y experimenta todo lo que GitHub tiene para ofrecer. Si tienes preguntas o necesitas ayuda, no dudes en dejar un comentario o compartir este artículo con alguien que pueda beneficiarse.&lt;/p&gt;

</description>
      <category>github</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
      <category>spanish</category>
    </item>
    <item>
      <title>Guía para Iniciarse en la Programación Funcional con C#</title>
      <dc:creator>Manuel Dávila Alarcón</dc:creator>
      <pubDate>Thu, 01 Aug 2024 15:26:45 +0000</pubDate>
      <link>https://dev.to/maadcode/guia-para-iniciarse-en-la-programacion-funcional-con-c-50o0</link>
      <guid>https://dev.to/maadcode/guia-para-iniciarse-en-la-programacion-funcional-con-c-50o0</guid>
      <description>&lt;p&gt;¿Alguna vez te has visto lidiando con funciones repetitivas y complicadas en tu código? La Programación Funcional puede ayudarte a simplificar esos problemas. Por ejemplo, las expresiones lambda y las funciones anónimas permiten escribir código más limpio y directo, haciendo que tareas que antes eran engorrosas se vuelvan mucho más manejables.&lt;/p&gt;

&lt;p&gt;Este paradigma de programación ofrece una forma diferente de pensar y escribir código, centrándose en funciones puras, inmutabilidad, y minimización de efectos secundarios. En este artículo, exploraremos los fundamentos de la programación funcional en C#, sus beneficios, y cómo puedes empezar a aplicarlos en tus proyectos.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A menudo, la programación funcional se asocia con lenguajes como Haskell o Scala, pero C# también ofrece un soporte robusto para este estilo de programación. Incluso si vienes de un fondo de programación orientada a objetos, estos conceptos pueden enriquecer tu enfoque y mejorar la calidad de tu código.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgagro6i73fjmz1sg5umq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgagro6i73fjmz1sg5umq.gif" alt="Gif de un cerebro explotando en el cosmo" width="200" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es la Programación Funcional?
&lt;/h2&gt;

&lt;p&gt;La Programación Funcional es un paradigma de programación que &lt;strong&gt;evita cambiar el estado y los datos mutables&lt;/strong&gt;. A diferencia de la programación orientada a objetos, que se centra en objetos y su interacción, la programación funcional se enfoca en la aplicación de funciones, lo que resulta en un código más predecible y fácil de razonar.&lt;/p&gt;

&lt;p&gt;En términos simples, se trata de construir software al componer funciones puras, que son funciones sin efectos secundarios y que siempre producen el mismo resultado dado el mismo conjunto de parámetros. Esto permite crear sistemas más modulares y testables.&lt;/p&gt;

&lt;p&gt;Algunos beneficios de la Programación Funcional:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Al reducir la complejidad del estado mutable y el comportamiento implícito, el código se vuelve más fácil de leer y mantener.&lt;/li&gt;
&lt;li&gt;Las funciones puras, al no depender de un estado externo, son más fáciles de probar, ya que siempre producirán el mismo resultado con los mismos parámetros.&lt;/li&gt;
&lt;li&gt;Al evitar el estado mutable, la programación funcional facilita el desarrollo de aplicaciones concurrentes, donde múltiples procesos pueden ejecutarse simultáneamente sin riesgo de colisión de datos.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Cuando utilizas un paradigma de programación, no estas atado a usar sólo este, puedes hacer una combinación de diferentes paradigmas de ser necesario. C# es un lenguaje orientado a objetos, así que al usar el paradigma Funcional, ya estas combinando estos 2 paradigmas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Características de la Programación Funcional
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Estado compartido 🔗
&lt;/h3&gt;

&lt;p&gt;En la programación funcional, la idea es evitar o minimizar el estado compartido. ¿Qué significa esto? Básicamente, que las funciones &lt;strong&gt;no dependen de variables globales&lt;/strong&gt; que puedan ser cambiadas por otras partes del programa. En vez de andar modificando cosas por todos lados, las funciones toman datos y devuelven nuevos datos, sin cambiar los originales.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Al reducir el estado compartido, se bajan los problemas relacionados con la concurrencia, que es cuando varias cosas intentan cambiar datos al mismo tiempo y causan errores.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Inmutabilidad 🔒
&lt;/h3&gt;

&lt;p&gt;La inmutabilidad es como una regla de oro en la programación funcional. Significa que una vez que se crea un dato, no se cambia. &lt;strong&gt;En lugar de modificar un objeto o una variable, lo que hacemos es crear uno nuevo&lt;/strong&gt; con los cambios que queramos. Aunque al principio pueda parecer menos eficiente, esto hace que el código sea más seguro y predecible.&lt;/p&gt;

&lt;p&gt;Por ejemplo, imagina que tienes un carrito de compras y querés agregar un producto, en vez de cambiar el carrito que ya tienes, creas uno nuevo que incluye el producto extra. Así, el carrito original no se toca y evitás problemas si otras partes del código lo están usando.&lt;/p&gt;

&lt;h3&gt;
  
  
  Efectos Secundarios ⚠️
&lt;/h3&gt;

&lt;p&gt;Los efectos secundarios ocurren cuando una función, además de devolver un valor, cambia algo en el estado del programa o interactúa con el exterior (como escribir en un archivo, actualizar una base de datos o llamadas a una API). En la programación funcional, la idea es &lt;strong&gt;minimizar estos efectos para que el código sea más fácil de entender y no cause sorpresas&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Delegados en &lt;code&gt;C#&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Antes de entrar en más conceptos de la programación Funcional, hablemos un poco de C# y algunas palabras reservadas que te serviran más adelante.&lt;/p&gt;

&lt;p&gt;Un delegado es un tipo que representa una referencia a un método. En C#, los delegados se utilizan para definir tipos de métodos que pueden ser asignados a variables, pasados como argumentos a otros métodos, o utilizados como callbacks&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;delegate&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;Operacion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EjemploDelegado&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;Sumar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Operacion&lt;/span&gt; &lt;span class="n"&gt;operacion&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Sumar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;operacion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// 8&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Func
&lt;/h3&gt;

&lt;p&gt;Func es un delegado genérico que encapsula un método que puede devolver un valor. Se puede usar para representar funciones con hasta 16 parámetros. El último tipo genérico en Func siempre representa el tipo de retorno.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;suma&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aquí, suma es una instancia de Func que representa una función que toma dos enteros como parámetros y devuelve un entero.&lt;/p&gt;

&lt;p&gt;Esto es muy similar a crear un método con un tipo de dato de retorno:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;suma&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Action
&lt;/h3&gt;

&lt;p&gt;Action es otro delegado genérico, similar a Func, pero se usa para métodos que no devuelven un valor (es decir, devuelven void). Action puede tener hasta 16 parámetros de entrada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;imprimir&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mensaje&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mensaje&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este caso, imprimir es una instancia de Action que representa un método que toma una cadena como argumento y no devuelve ningún valor.&lt;/p&gt;

&lt;p&gt;Esto es muy similar a crear un método de tipo void:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;imprimir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;mensaje&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mensaje&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Predicate
&lt;/h3&gt;

&lt;p&gt;Un Predicate es un delegado que encapsula un método que toma un argumento de tipo T y devuelve un bool. Este delegado se usa frecuentemente en métodos de colecciones genéricas, como List, para encontrar o filtrar elementos que cumplan con ciertos criterios.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Predicate&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;esPar&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, esPar es un Predicate que representa una función para determinar si un número es par.&lt;/p&gt;

&lt;p&gt;Esto es muy similar a crear un método que retorne un tipo bool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;esPar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;¡Ahora sí! Retomemos los conceptos de la Programación Funcional utilizando los delegados aprendidos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Funciones Puras
&lt;/h2&gt;

&lt;p&gt;Las funciones puras son aquellas que &lt;strong&gt;siempre devuelven el mismo resultado cuando se les da el mismo input&lt;/strong&gt; y no causan efectos secundarios. Esto significa que no cambian el estado de nada fuera de ellas ni dependen de algo que pueda cambiar fuera de su ámbito.&lt;/p&gt;

&lt;p&gt;Imagina que tienes una función que calcula el precio final de un producto aplicando un descuento:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;CalcularPrecioFinal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;precioBase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;descuento&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;precioBase&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;precioBase&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;descuento&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta función es pura porque siempre devolverá el mismo resultado si se le pasa el mismo precioBase y descuento, y no cambia nada más en el sistema.&lt;/p&gt;

&lt;p&gt;Como no existe una lógica compleja, podemos refactorizar utilizando un delegado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;CalcularPrecioFinal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;precioBase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;descuento&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;precioBase&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;precioBase&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;descuento&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Expresiones Lambda y Funciones Anónimas
&lt;/h2&gt;

&lt;p&gt;Las expresiones lambda y las funciones anónimas son &lt;strong&gt;formas de definir funciones&lt;/strong&gt; rápidas y temporales, sin necesidad de nombrarlas explícitamente. Son muy útiles para operaciones sencillas o &lt;strong&gt;para pasar funciones como parámetros&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;En el ejemplo anterior "(precioBase, descuento) =&amp;gt; precioBase - (precioBase * descuento)" era nuestra expresión lambda.&lt;/p&gt;

&lt;p&gt;Probemos con otro ejemplo, supongamos que tienes una lista de productos y quieres obtener sólo los nombres de los productos en oferta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;nombresProductosEnOferta&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;productos&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;producto&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;producto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EsEnOferta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;producto&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;producto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nombre&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aquí, producto =&amp;gt; producto.EsEnOferta y producto =&amp;gt; producto.Nombre son expresiones lambda que se usan para filtrar y proyectar los productos de la lista.&lt;/p&gt;

&lt;h2&gt;
  
  
  Composicion de Funciones
&lt;/h2&gt;

&lt;p&gt;La composición de funciones es la práctica de &lt;strong&gt;combinar funciones pequeñas y simples para construir funciones más complejas&lt;/strong&gt;. En programación funcional, es común crear funciones reutilizables que se pueden combinar de diversas maneras.&lt;/p&gt;

&lt;p&gt;Puedes tener funciones separadas para calcular impuestos y descuentos, y luego componerlas para obtener el precio final:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;aplicarImpuesto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;precio&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;precio&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;1.18m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;aplicarDescuento&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;precio&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;precio&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;0.90m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;calcularPrecioFinal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;precio&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;aplicarDescuento&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;aplicarImpuesto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;precio&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, calcularPrecioFinal es una función compuesta que aplica primero el impuesto y luego el descuento al precio de un producto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Funciones de Orden Superior
&lt;/h2&gt;

&lt;p&gt;Las funciones de orden superior son aquellas que &lt;strong&gt;pueden tomar otras funciones como argumentos o devolverlas como resultados&lt;/strong&gt;. Esto es útil para crear funciones más generales y reutilizables.&lt;/p&gt;

&lt;p&gt;Si quieres filtrar productos según diferentes criterios (por ejemplo, productos en oferta o productos baratos), puedes usar una función de orden superior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;FiltrarProductos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;productos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Predicate&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;criterio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;productos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;criterio&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;productosEnOferta&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;FiltrarProductos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;productos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;producto&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;producto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EsEnOferta&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;productosEconomicos&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;FiltrarProductos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;productos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;producto&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;producto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Precio&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;50.0m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este caso, FiltrarProductos es una función de orden superior que recibe un predicado (criterio) para filtrar productos.&lt;/p&gt;

&lt;p&gt;Usar un enfoque funcional puede mejorar la mantenibilidad y escalabilidad de tus proyectos. Esto es especialmente útil en sistemas grandes o de larga vida, donde el código limpio y modular es crucial.&lt;/p&gt;

&lt;p&gt;Si eres nuevo en la programación funcional, comienza adoptando pequeñas prácticas en tus proyectos actuales. Utiliza expresiones lambda, funciones puras y trata de minimizar el estado mutable. Experimenta con delegados como Func, Action y Predicate para familiarizarte con su uso.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Además, considera el uso de herramientas y bibliotecas que faciliten la programación funcional en C#, como LINQ, que permite realizar consultas y manipulaciones de datos de manera funcional.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La programación funcional puede parecer un cambio radical si vienes de un fondo orientado a objetos, pero los beneficios en términos de claridad, mantenibilidad y testabilidad del código valen la pena. Espero que este contenido te haya sido de utilidad y te brinde un acercamiento a la programación funcional con C#.&lt;/p&gt;

&lt;p&gt;!Happy coding! ✨&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>codenewbie</category>
      <category>spanish</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Explorando los Fundamentos de la Programación Orientada a Objetos en C#</title>
      <dc:creator>Manuel Dávila Alarcón</dc:creator>
      <pubDate>Wed, 31 Jul 2024 01:47:25 +0000</pubDate>
      <link>https://dev.to/maadcode/explorando-los-fundamentos-de-la-programacion-orientada-a-objetos-en-c-284d</link>
      <guid>https://dev.to/maadcode/explorando-los-fundamentos-de-la-programacion-orientada-a-objetos-en-c-284d</guid>
      <description>&lt;p&gt;¿Te has encontrado alguna vez con código tan desordenado que parece un rompecabezas imposible de resolver? En el mundo actual, donde dependemos de aplicaciones para casi todo, mantener el código organizado y eficiente es crucial. Aquí es donde entra en juego la Programación Orientada a Objetos (POO). Este paradigma nos ayuda a que nuestros proyectos sean más fáciles de entender, mantener y expandir.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Es cierto que incluso con POO, el código puede volverse desordenado, especialmente en sistemas legacy que han evolucionado sin una dirección clara. Sin embargo, al adoptar buenas prácticas de POO, podemos minimizar estos problemas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcyfoi3yotp9ttz3j6zy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcyfoi3yotp9ttz3j6zy.gif" alt="Imagen de perro de caricatura en incendio " width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En este artículo, vamos a desglosar los conceptos básicos de la POO en C#, explicando por qué es tan valiosa y cómo puedes usarla en tus propios proyectos.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es la Programación Orientada a Objetos?
&lt;/h2&gt;

&lt;p&gt;La Programación Orientada a Objetos (POO) es un paradigma de programación que utiliza "objetos" para representar cosas del mundo real. ¿Cómo funciona? Imagina que tienes una aplicación y quieres crear algo que represente un "Personaje" en un juego. Ese personaje puede tener atributos como salud y fuerza, y métodos para atacar o defenderse. Así, en lugar de escribir todo de una manera desordenada, puedes organizar tu código en objetos que son fáciles de manejar.&lt;/p&gt;

&lt;p&gt;Probablemente, alguna vez te pasó que el código que hiciste hace una semana ya no lo recuerdas 😅, no lo podemos evitar pero podemos hacerlo más fácil de manejar con POO. Alguno de sus beneficios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Organiza el código de una forma más entendible, haciendo que sea más fácil trabajar en equipo o volver al proyecto después de un tiempo.&lt;/li&gt;
&lt;li&gt;Facilita la actualización y mejora del software, ya que puedes agregar nuevas funcionalidades sin romper todo lo que ya funciona.&lt;/li&gt;
&lt;li&gt;Promueve buenas prácticas de programación como el encapsulamiento, la herencia y el polimorfismo, lo que se traduce en un código más limpio y reutilizable.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;¡Ojo! La POO no es la solución mágica. Incluso con este enfoque, es posible que el código se vuelva un quilombo, sobre todo en sistemas antiguos o mal diseñados. Por eso, es clave seguir buenas prácticas y mantener el código lo más prolijo posible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5e5e28if4jjwr5dk9h3x.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5e5e28if4jjwr5dk9h3x.gif" alt="Persona con una varita mágica" width="245" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Entender bien los conceptos de la POO es fundamental para evitar los errores comunes y sacar el máximo provecho de este paradigma. No te olvides de practicar y de leer código de otros desarrolladores para ver cómo aplican estos conceptos en situaciones reales.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Clases y Objetos en &lt;code&gt;C#&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;En la POO, las clases son como los planos o moldes para crear objetos. Imagina una clase como una receta de cocina que define qué ingredientes se necesitan y cómo combinarlos para hacer un plato. En nuestro caso, la "receta" es una clase, y los "platos" que creamos a partir de esa receta son los objetos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clase
&lt;/h3&gt;

&lt;p&gt;Una clase en C# define un tipo de datos y especifica qué propiedades y métodos tendrá. Pensemos en un videojuego: tienes varios personajes, y cada uno tiene características y habilidades diferentes. Para manejar esto, podríamos crear una clase llamada Personaje que sirva como base para todos los personajes del juego, con propiedades como Nombre, Vida, Fuerza, y métodos como Atacar() y Defender().&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Personaje&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Nombre&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Fuerza&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nombre&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; ataca con una fuerza de &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Fuerza&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Defender&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nombre&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; se defiende, reduciendo el daño."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx9dhnop1s5axn7dyze06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx9dhnop1s5axn7dyze06.png" alt="Imagen de un maniqui para referenciar a un molde o plantilla" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Objetos
&lt;/h3&gt;

&lt;p&gt;Un objeto es una instancia concreta de una clase. Imagina que la clase Personaje es el diseño de un personaje; un objeto sería un personaje específico dentro del juego, como un guerrero o un mago, cada uno con sus propios valores para Nombre, Vida, y Fuerza.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Personaje&lt;/span&gt; &lt;span class="n"&gt;guerrero&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Personaje&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;guerrero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nombre&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Thorin"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;guerrero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;150&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;guerrero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fuerza&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;75&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;guerrero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Thorin ataca con una fuerza de 75.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, guerrero es un objeto de la clase Personaje que representa a un personaje específico en el videojuego. Cada objeto puede tener valores diferentes para las mismas propiedades, permitiendo una gran flexibilidad y personalización en el juego.&lt;/p&gt;

&lt;h3&gt;
  
  
  Propiedades
&lt;/h3&gt;

&lt;p&gt;Las propiedades en C# actúan como características del objeto para almacenar datos. Funcionan como variables, pero con un mayor control sobre cómo se asignan y recuperan los valores. En el caso del videojuego, las propiedades de la clase Personaje incluyen atributos como Nombre, Vida y Fuerza.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Personaje&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Nombre&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Fuerza&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Estas propiedades permiten acceder y modificar los atributos del personaje de manera controlada. Por ejemplo, si quieres ajustar la vida de un personaje cuando recibe daño, simplemente actualizás la propiedad Vida.&lt;/p&gt;

&lt;h3&gt;
  
  
  Métodos
&lt;/h3&gt;

&lt;p&gt;Los métodos son funciones definidas dentro de una clase que permiten la comunicación entre objetos. En nuestro videojuego, los métodos Atacar() y Defender() definen cómo los personajes interactúan entre sí.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Personaje&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nombre&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; ataca con una fuerza de &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Fuerza&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Defender&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nombre&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; se defiende, reduciendo el daño."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora imaginamos que queremos que nuestro personaje Thorin ataque y luego se defienda. Utilizaríamos los métodos de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Personaje&lt;/span&gt; &lt;span class="n"&gt;thorin&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Personaje&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;thorin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nombre&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Thorin"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;thorin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;150&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;thorin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fuerza&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;75&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;thorin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Thorin ataca con una fuerza de 75.&lt;/span&gt;
&lt;span class="n"&gt;thorin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Defender&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Thorin se defiende, reduciendo el daño.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;[Imagen de un personaje en accion]&lt;/p&gt;

&lt;h3&gt;
  
  
  Constructores
&lt;/h3&gt;

&lt;p&gt;Un constructor es un método especial en una clase que se llama automáticamente cuando se crea un nuevo objeto de esa clase. Su propósito principal es inicializar los atributos del objeto. En C#, un constructor tiene el mismo nombre que la clase y no tiene un tipo de retorno.&lt;/p&gt;

&lt;p&gt;En este ejemplo, el constructor Personaje(string nombre) se utiliza para inicializar el nombre del personaje y establecer valores predeterminados para la vida y la fuerza:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Personaje&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Nombre&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Fuerza&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Constructor&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Personaje&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Nombre&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Fuerza&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Cada vez que utilizas "new" haces uso del constructor para crear un objeto.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fymqlgfda315vsyxzahgx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fymqlgfda315vsyxzahgx.png" alt="Imagen de una fabrica de construcción de maniquis para referenciar a la instancia de un clase" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sobrecarga
&lt;/h3&gt;

&lt;p&gt;La sobrecarga de métodos, incluido el constructor, permite definir múltiples métodos con el mismo nombre pero con diferentes parámetros. Esto es útil para proporcionar diversas maneras de inicializar un objeto.&lt;/p&gt;

&lt;p&gt;Por ejemplo, podríamos tener varios constructores para Personaje que permitan diferentes niveles de detalle en la creación de un personaje:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Personaje&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Nombre&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Fuerza&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Constructor 1: Sólo nombre&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Personaje&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Nombre&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Fuerza&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Constructor 2: Nombre y vida&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Personaje&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;vida&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Nombre&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vida&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Fuerza&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Constructor 3: Nombre, vida y fuerza&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Personaje&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;vida&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fuerza&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Nombre&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vida&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Fuerza&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fuerza&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aquí, hemos definido tres constructores diferentes para Personaje, permitiendo crear objetos con solo el nombre, con nombre y vida, o con nombre, vida y fuerza. Esto da flexibilidad para inicializar objetos según las necesidades del juego.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;La sobrecarga también se puede utilizar en los métodos de la clase, no sólo en constructores.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Principios fundamentales de la POO
&lt;/h2&gt;

&lt;p&gt;La Programación Orientada a Objetos se basa en cuatro principios clave que ayudan a construir software más modular, reutilizable y fácil de mantener. Estos principios son Encapsulamiento, Herencia, Polimorfismo, y Abstracción. Vamos a ver de qué se tratan con ejemplos aplicados al desarrollo de un videojuego.&lt;/p&gt;

&lt;h3&gt;
  
  
  Encapsulamiento
&lt;/h3&gt;

&lt;p&gt;El encapsulamiento consiste en ocultar los detalles internos de un objeto y exponer sólo lo necesario. Esto se logra mediante el uso de propiedades y métodos públicos para interactuar con el objeto, mientras que los detalles internos se mantienen privados.&lt;/p&gt;

&lt;p&gt;En el contexto de un videojuego, el encapsulamiento asegura que los atributos de un personaje, como su vida o fuerza, no sean modificados directamente desde fuera de la clase. En cambio, se utilizan métodos para alterar estos atributos, lo que permite agregar lógica adicional, como validaciones.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Personaje&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;vida&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Defensa&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Vida&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;get&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;vida&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;set&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;vida&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
                &lt;span class="n"&gt;vida&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;RecibirDano&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;dano&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;danoFinal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dano&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Defensa&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;danoFinal&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;danoFinal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, el atributo vida es privado, y se accede a él mediante la propiedad Vida. El método RecibirDano() controla cómo se reduce la vida del personaje, asegurando que no baje de cero.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;El encapsulamiento no sólo protege los datos de cambios no deseados, sino que también facilita el mantenimiento del código al centralizar la lógica relacionada.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Herencia
&lt;/h3&gt;

&lt;p&gt;La herencia permite crear una nueva clase que reutiliza, extiende o modifica el comportamiento de otra clase. Es como crear una plantilla general y luego hacer variantes de ella para casos específicos.&lt;/p&gt;

&lt;p&gt;En nuestro videojuego, podemos tener una clase base Personaje y luego derivar clases como Guerrero o Mago que heredan atributos y métodos de Personaje, pero con características adicionales.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Personaje&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Nombre&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Vida&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Atacar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nombre&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; ataca."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Guerrero&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Personaje&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Fuerza&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;AtacarConEspada&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nombre&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; ataca con una espada con fuerza de &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Fuerza&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Mago&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Personaje&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Mana&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;LanzarHechizo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nombre&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; lanza un hechizo utilizando &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Mana&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; de mana."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aquí, Guerrero y Mago heredan de Personaje, compartiendo propiedades comunes como "Nombre" y "Vida", pero también añadiendo su propia funcionalidad específica.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;La herencia debe usarse con cuidado, ya que puede llevar a una estructura de clases compleja y difícil de mantener si se abusa de ella.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Polimorfismo
&lt;/h3&gt;

&lt;p&gt;El polimorfismo permite a los objetos de diferentes clases ser tratados como objetos de una clase base común. En términos simples, permite usar un método de la misma manera para diferentes tipos de objetos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void RealizarAccion(Personaje personaje)
{
    personaje.Atacar();
}

Guerrero guerrero = new Guerrero { Nombre = "Thorin", Fuerza = 100 };
Mago mago = new Mago { Nombre = "Gandalf", Mana = 200 };

RealizarAccion(guerrero); // Thorin ataca con una espada con fuerza de 100.
RealizarAccion(mago); // Gandalf lanza un hechizo utilizando 200 de mana.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, aunque RealizarAccion llama al mismo método "Atacar" en ambos casos, la implementación específica de cada clase derivada es la que se ejecuta.&lt;/p&gt;

&lt;h3&gt;
  
  
  Abstracción
&lt;/h3&gt;

&lt;p&gt;La abstracción consiste en simplificar la complejidad del sistema al mostrar sólo los detalles esenciales y ocultar los innecesarios. En POO, esto se logra mediante clases abstractas y interfaces, que definen una estructura común sin implementar todos los detalles.&lt;/p&gt;

&lt;p&gt;Imaginemos que queremos definir una interfaz IPoder para habilidades especiales que todos los personajes deben tener, pero cada personaje puede implementar estas habilidades de manera diferente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IPoder&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;UsarPoder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Guerrero&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Personaje&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IPoder&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;UsarPoder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nombre&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; usa su poder especial: Golpe Feroz."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Mago&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Personaje&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IPoder&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;UsarPoder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nombre&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; usa su poder especial: Llamas Místicas."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, Guerrero y Mago implementan la interfaz IPoder, cada uno proporcionando su propia versión del método "UsarPoder".&lt;/p&gt;

&lt;p&gt;Podrías realizar el mismo ejemplo utilizando una clase abstracta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="n"&gt;Poder&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;UsarPoder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Guerrero&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Poder&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;UsarPoder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nombre&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; usa su poder especial: Golpe Feroz."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Mago&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Poder&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;UsarPoder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nombre&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; usa su poder especial: Llamas Místicas."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El problema es que al ser una clase, no podrás heredera de ninguna otra. Eso a su vez genera un alto acoplamiento. Es por eso que se recomienda utilizar una interface sobre las clases abstractas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cohesión y Acoplamiento
&lt;/h2&gt;

&lt;p&gt;En la Programación Orientada a Objetos, dos conceptos clave para escribir código limpio y manejable son la cohesión y el acoplamiento.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cohesión&lt;/strong&gt; se refiere a qué tan bien se agrupan las responsabilidades dentro de una clase. Una clase con alta cohesión tiene un propósito claro y realiza un conjunto específico de tareas. Por ejemplo, en un videojuego, una clase Inventario debería manejar todo lo relacionado con los ítems del jugador, y no encargarse de las habilidades o el estado del personaje&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Acoplamiento&lt;/strong&gt; es la medida en que una clase depende de otras. El bajo acoplamiento es deseable porque permite que los cambios en una clase no afecten otras. Imaginemos que tenemos una clase Arma y una clase Personaje. Si Personaje depende demasiado de la estructura interna de Arma, cualquier cambio en Arma podría requerir modificaciones en Personaje. Mantener bajo acoplamiento facilita la reutilización de código y mejora la mantenibilidad.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Al diseñar tus clases, trata de que cada una tenga una única responsabilidad clara (alta cohesión) y minimiza las dependencias entre ellas (bajo acoplamiento). Esto hará que tu código sea más fácil de entender, mantener y expandir.&lt;/p&gt;

&lt;p&gt;Una vez que domines estos conceptos podrás mejorar tu código aún más con los principios SOLID y patrones de diseño. 😎&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Espero que este post te haya sido de utilidad para entender mejor la POO en C#. Aplica esto en proyectos personales y no compliques el diseño de clases innecesariamente; a veces, la solución más simple es la mejor.&lt;/p&gt;

&lt;p&gt;!Happing coding! ☕&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>spanish</category>
      <category>oop</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Lógica de programación con estructuras de control en C#</title>
      <dc:creator>Manuel Dávila Alarcón</dc:creator>
      <pubDate>Tue, 30 Jul 2024 02:57:04 +0000</pubDate>
      <link>https://dev.to/maadcode/logica-de-programacion-con-estructuras-de-control-en-c-2c8g</link>
      <guid>https://dev.to/maadcode/logica-de-programacion-con-estructuras-de-control-en-c-2c8g</guid>
      <description>&lt;p&gt;¿Alguna vez te has preguntado cómo funcionan las aplicaciones que usas todos los días? Desde un simple juego en tu teléfono hasta una aplicación bancaria que gestiona tus finanzas, todos estos programas necesitan tomar decisiones y realizar acciones repetitivas. Y eso es exactamente lo que hacen las estructuras de control en C#.&lt;/p&gt;

&lt;p&gt;Imagina que estás desarrollando una aplicación para un servicio de entrega de alimentos. Quieres que la aplicación muestre un mensaje diferente dependiendo de si el pedido está en camino, entregado o cancelado. Aquí es donde entra en juego el condicional "if".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatypzf4pk74fugoh6v4o.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatypzf4pk74fugoh6v4o.gif" alt="Imagen de una caricatura con un letrero para decidir el camino de la izquierda o derecha" width="480" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O tal vez estás construyendo una plataforma de streaming que personaliza recomendaciones de series y películas. Necesitas analizar el historial de visualizaciones de cada usuario para sugerir contenido nuevo. Aquí, los bucles "for" y "foreach" son esenciales para recorrer y procesar los datos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F54whwxtbts64omfk7vwg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F54whwxtbts64omfk7vwg.gif" alt="Imagen de un loop infinito al ingresar a una puerta" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aquí aprenderemos cómo utilizar las estructuras de control en C# para hacer que nuestros programas tomen el camino que nosotros queremos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estructuras condicionales
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Condicional If
&lt;/h3&gt;

&lt;p&gt;El condicional "if" nos ayuda a decidir &lt;strong&gt;si una parte del código se ejecuta o no, dependiendo de si una condición es verdadera&lt;/strong&gt;. Piénsalo como tomar decisiones en tiempo real en función de lo que está sucediendo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyi53sneji4vtd2veqhcw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyi53sneji4vtd2veqhcw.png" alt="Imagen de un diagrama de flujo con una estructura condicional if" width="748" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagina que estás desarrollando una aplicación para un servicio de entrega de alimentos. Quieres que los usuarios reciban una notificación cuando su pedido esté listo para ser recogido. Podrías usar un condicional "if" para verificar si el pedido ha cambiado su estado a "listo para recoger". Si es así, envías una notificación al usuario para informarle.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Estado&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;EstadoPedido&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListoParaRecoger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;EnviarNotificacion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tu pedido está listo para recoger"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, el condicional "if" verifica si el usuario está inactivo (es decir, "usuarioActivo" es falso). Si lo está, se envía una notificación al usuario.&lt;/p&gt;

&lt;p&gt;En este ejemplo, el condicional "if" verifica si el estado del pedido es "ListoParaRecoger". Si la condición es verdadera, se envía una notificación al usuario para informarle que puede ir a recoger su pedido.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Condicional If - Else
&lt;/h3&gt;

&lt;p&gt;El condicional "if - else" nos ayuda a manejar situaciones donde hay más de una posible acción a tomar, dependiendo de si una condición es verdadera o falsa. Es como decir &lt;strong&gt;"si esto cumple, haz esto; de lo contrario, haz lo otro"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fya6bg82zmmjwwj12zuzf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fya6bg82zmmjwwj12zuzf.png" alt="Imagen de un diagrama de flujo con una estructura condicional if - else" width="800" height="814"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Supongamos que quieres mostrar un mensaje diferente a los usuarios dependiendo de si su pedido ha sido confirmado o no. Aquí es donde el condicional "if - else" resulta útil.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Estado&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;EstadoPedido&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Confirmado&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;MostrarMensaje&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tu pedido ha sido confirmado y está siendo preparado."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;MostrarMensaje&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Lo sentimos, tu pedido no ha podido ser confirmado. Por favor, intenta nuevamente."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, el condicional "if - else" verifica si el estado del pedido es Confirmado. Si el pedido está confirmado, se muestra un mensaje indicando que el pedido está siendo preparado. De lo contrario, se muestra un mensaje informando al usuario que el pedido no ha podido ser confirmado. Esto permite manejar diferentes estados del pedido de manera clara y estructurada.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Condicional If - Else If - Else
&lt;/h3&gt;

&lt;p&gt;Las condicionales "if - else if - else" nos permiten evaluar una serie de condiciones en secuencia y ejecutar el bloque de código correspondiente a la primera condición que se cumpla. Es como decir &lt;strong&gt;"si esto cumple, haz esto; de lo contrario, si esto otro cumple, haz lo otro; y si ninguna de las anteriores sucede, haz esto otro"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftj2j56v2e9pa1hyh2qjp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftj2j56v2e9pa1hyh2qjp.png" alt="Imagen de un diagrama de flujo con una estructura condicional if - else if - else" width="800" height="876"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si estas desarrollando un sistema de cálculo de tarifas de envío para una tienda en línea y dependiendo del peso del paquete y la distancia de envío, el sistema debe calcular diferentes tarifas de envío correspondiente, acá nos ayudaría esta condicional.&lt;/p&gt;

&lt;p&gt;Imagina que necesitas calcular el tiempo estimado de entrega en función de la distancia y el tráfico, acá nos ayudaría esta condicional.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peso&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tarifaEnvio&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5.99&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peso&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tarifaEnvio&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;9.99&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peso&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tarifaEnvio&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;14.99&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tarifaEnvio&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;19.99&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;MostrarTarifaEnvio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tarifaEnvio&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Es importante ordenar las condiciones de manera lógica y coherente para evitar errores y mejorar la legibilidad del código. El orden de tus condicionales es crucial, ya que una vez que se cumpla una condición, no se evaluarán las siguientes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Existen los "if anidados", que se utilizan para evaluar múltiples condiciones de manera jerárquica y secuencial. Esto significa que dentro de un "if" se coloca otro bloque de "if", permitiendo tomar decisiones más complejas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Por ejemplo, si necesitas determinar el tipo de oferta que se le debe mostrar a un cliente basado en su historial de pedidos y la disponibilidad actual de productos, puedes usar if anidados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cliente&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HistorialPedidos&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;producto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Disponibilidad&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Alta"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;MostrarOfertaEspecial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Descuento del 20% en tu próximo pedido"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;MostrarOfertaEspecial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Descuento del 10% en tu próximo pedido"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;MostrarOfertaEspecial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Obtén un 5% de descuento al referir a un amigo"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Es una buena práctica refactorizar estos if anidados en un único "if - else if - else" cuando sea posible, para simplificar el código y mejorar su legibilidad.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Switch Case
&lt;/h3&gt;

&lt;p&gt;El "switch case" es como una centralita de opciones que elige qué hacer basándose en el valor de una variable. &lt;strong&gt;Es especialmente útil cuando tienes varias opciones y cada una requiere una respuesta diferente&lt;/strong&gt;. Es una alternativa más ordenada al uso de múltiples "if - else if - else".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6mqoa5ckxd2bubekqwos.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6mqoa5ckxd2bubekqwos.png" alt="Imagen de un diagrama de flujo con una estructura condicional switch" width="800" height="1057"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si en tu aplicación quieres mostrar mensajes personalizados a los usuarios según el estado de su pedido, utilizar un "switch case" resulta ideal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Estado&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;EstadoPedido&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pendiente&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;MostrarMensaje&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tu pedido está pendiente de confirmación."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;EstadoPedido&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Confirmado&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;MostrarMensaje&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"¡Genial! Tu pedido ha sido confirmado y pronto estará en camino."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;EstadoPedido&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EnCamino&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;MostrarMensaje&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tu pedido está en camino. ¡Prepárate para disfrutar!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;EstadoPedido&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entregado&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;MostrarMensaje&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tu pedido ha sido entregado. ¡Buen provecho!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;EstadoPedido&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Cancelado&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;MostrarMensaje&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Lo sentimos, tu pedido ha sido cancelado."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;MostrarMensaje&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Estado del pedido desconocido. Por favor, contacta con el soporte."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada "case" corresponde a un estado específico, y el programa ejecuta el bloque de código correspondiente solo si el valor del estado coincide. La instrucción break es importante porque evita que el código continúe ejecutando los siguientes bloques de "case" una vez que se encuentra una coincidencia.&lt;/p&gt;

&lt;p&gt;El "switch case" hace que tu código sea más organizado, especialmente cuando hay varias condiciones posibles. Además, mejora la legibilidad y facilita la comprensión de lo que el programa está haciendo en cada situación.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Operador ternario
&lt;/h3&gt;

&lt;p&gt;El operador ternario es útil para decisiones rápidas y sencillas, donde solo necesitas asignar diferente valor entre dos opciones. Es como decir "si esto es verdadero, asigna tal valor; si no, asigna esto otro", pero en una sola línea de código.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ccstq1wzixr7k2328xi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ccstq1wzixr7k2328xi.png" alt="Imagen de un diagrama de flujo con una estructura condicional con operador ternario" width="800" height="814"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagina que en tu aplicación quieres mostrar un mensaje que indique si el tiempo estimado de llegada es rápido o lento, dependiendo de si es menor o mayor a 30 minutos. El operador ternario es perfecto para este tipo de decisiones rápidas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;mensajeTiempoEntrega&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tiempoEntrega&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s"&gt;"Entrega rápida, buen provecho!"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Tu pedido llegará pronto, gracias por tu paciencia."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;MostrarMensaje&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mensajeTiempoEntrega&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, el operador ternario evalúa la condición tiempoEntrega &amp;lt; 30. Si es verdadera, asigna la cadena de texto "Entrega rápida, buen provecho!" a la variable mensajeTiempoEntrega. Si es falsa, asignará "Tu pedido llegará pronto, gracias por tu paciencia.".&lt;/p&gt;

&lt;p&gt;Si no tuvieramos el operador ternario, utilizariamos el if-else de la siguiente forma para tener el mismo comportamiento:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;mensajeTiempoEntrega&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tiempoEntrega&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;mensajeTiempoEntrega&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Entrega rápida, buen provecho!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;mensajeTiempoEntrega&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Tu pedido llegará pronto, gracias por tu paciencia."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;MostrarMensaje&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mensajeTiempoEntrega&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ten en cuenta que este operador sólo se debe usarse para condiciones simples que su acción sea la asignación de algún valor a una variable&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estructuras repetitivas
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6. Bucle While
&lt;/h3&gt;

&lt;p&gt;El bucle While se utiliza para repetir un bloque de código mientras una condición sea verdadera. Es ideal &lt;strong&gt;cuando no sabes cuántas veces necesitas repetir el ciclo&lt;/strong&gt; porque la condición se evalúa antes de cada iteración.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj20l3f2w71jfkiu4vg7j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj20l3f2w71jfkiu4vg7j.png" alt="Imagen de un diagrama de flujo con una estructura repetitiva while" width="660" height="1366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagina que en una aplicación de streaming de películas y series, necesitas verificar continuamente si hay una nueva recomendación para el usuario mientras está viendo contenido.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TerminoDeVerPelicula&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;nuevaRecomendacion&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ObtenerSiguienteRecomendacion&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;MostrarRecomendacion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nuevaRecomendacion&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, el bucle while sigue mostrando recomendaciones al usuario hasta que termine de ver la película.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Evita modificar variables externas dentro del bucle que podrían cambiar la lógica de control inesperadamente. A esto se le conoce como "efecto secundario".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  7. Bucle Do While
&lt;/h3&gt;

&lt;p&gt;La estructura Do While es similar al While, pero con una diferencia clave: siempre ejecuta el bloque de código al menos una vez antes de verificar la condición. Es útil &lt;strong&gt;cuando deseas que el código se ejecute al menos una vez&lt;/strong&gt; sin importar la condición inicial.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjut4mnmqo37i7m2m8c5a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjut4mnmqo37i7m2m8c5a.png" alt="Imagen de un diagrama de flujo con una estructura repetitiva do while" width="556" height="1366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Siguiendo con el ejemplo de la aplicación de streaming, imagina que quieres mostrar un resumen de los episodios de una serie, y si o si necesitas que se muestre el primero.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;MostrarResumen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;episodio&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;episodio&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ObtenerSiguienteEpisodio&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;episodio&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este caso, el bucle do while muestra un resumen del episodio actual y luego obtiene el siguiente episodio. Esto se repite hasta que no haya más episodios disponibles.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Bucle For
&lt;/h3&gt;

&lt;p&gt;El bucle For es ideal para situaciones en las que &lt;strong&gt;conoces de antemano cuántas veces quieres repetir&lt;/strong&gt; un bloque de código. Se usa comúnmente para iterar sobre una secuencia de números o índices.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flfeprm4np5j3kxbyicgh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flfeprm4np5j3kxbyicgh.png" alt="Imagen de un diagrama de flujo con una estructura repetitiva for" width="660" height="1366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Por ejemplo, en tu aplicación de streaming, podrías usar un bucle for para mostrar los primeros 5 trailers más populares para el usuario.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;MostrarTrailer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;listaDeTrailers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aquí, el bucle for se ejecuta cinco veces, mostrando los trailers de la lista en el orden de popularidad.&lt;/p&gt;

&lt;p&gt;Siempre debes asegurarte que exista el indice (nuestra variable i) al que accedes. Por ejemplo, si esa lista de trailers solo tuviera 4 elementos, al acceder al 5to obtendríamos un error.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Bucle Foreach
&lt;/h3&gt;

&lt;p&gt;Por último el bucle Foreach se utiliza para &lt;strong&gt;iterar a través de colecciones como listas o arreglos&lt;/strong&gt; de manera sencilla. Es ideal cuando quieres recorrer todos los elementos de una colección sin preocuparte por los índices.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flcmw0697lhu56cfdmbcp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flcmw0697lhu56cfdmbcp.png" alt="Imagen de un diagrama de flujo con una estructura repetitiva foreach" width="660" height="1366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Por ejemplo, en el caso anterior sólo queriamos recorrer 5 elementos, pero si quisieramos recorrer todos los trailers, el foreach sería el indicado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;trailer&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;listaDeTrailers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;MostrarTrailer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trailer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto es una herramienta poderosa para simplificar el código y evitar errores de índice. Sin embargo, ten en cuenta que no puedes modificar la colección original dentro del bucle, es decir "listaDeTrailers". Para ese tipo de cambios, es mejor usar un bucle for.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Asegurate de que toda estructura repetitiva o bucle cumpla con la condición para finalizar, así no tienes un bucle infinito que genere el famoso StackOverflowException o algún otro.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Así que ahí lo tienes, ¡una inmersión completa al mundo de la lógica de programación utilizando C#! &lt;/p&gt;

&lt;p&gt;Puedes poner en práctica tu lógica de programación en plataformas como &lt;a href="https://www.codewars.com/" rel="noopener noreferrer"&gt;Codewars&lt;/a&gt; o &lt;a href="https://www.hackerrank.com/" rel="noopener noreferrer"&gt;Hackerrank&lt;/a&gt;. Te recomiendo empezar con la lógica de resolver el problema antes de pensar en como hacer un código limpio. Una vez que tengas la lógica funcionando, piensa en como puedes optimizarlo.&lt;/p&gt;

&lt;p&gt;¿Quién diría que unos simples "if", "while" y "for" podrían ser tan poderosos? Pero recuerda, con gran poder viene gran responsabilidad... ¡y también muchos errores de compilación! 😅&lt;/p&gt;

&lt;p&gt;¡Happing coding! 🚀&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>programming</category>
      <category>spanish</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>La Importancia del Unit Testing en el Desarrollo de Software</title>
      <dc:creator>Manuel Dávila Alarcón</dc:creator>
      <pubDate>Sat, 22 Jul 2023 23:08:18 +0000</pubDate>
      <link>https://dev.to/maadcode/la-importancia-del-unit-testing-en-el-desarrollo-de-software-gij</link>
      <guid>https://dev.to/maadcode/la-importancia-del-unit-testing-en-el-desarrollo-de-software-gij</guid>
      <description>&lt;p&gt;Cuando se trata de desarrollar software de calidad, una de las herramientas más poderosas que tenemos a nuestro alcance es el Unit Testing.&lt;/p&gt;

&lt;p&gt;En este artículo, exploraremos de forma sencilla y accesible todos los aspectos clave sobre los unit tests. Descubrirás sus beneficios, cómo se estructuran, técnicas para nombrarlos adecuadamente, qué son los mocks y el Code Coverage, además de las mejores prácticas para escribir unit tests efectivos.&lt;/p&gt;

&lt;p&gt;Antes de iniciar quiero que darte un ejemplo de que ocurriría en un proyecto sin pruebas unitarias.&lt;/p&gt;

&lt;p&gt;Imagina que estás desarrollando una nueva aplicación web y has llegado a la fase de pruebas en donde esperas cruzar los dedos para no encontrar errores. Pero, sorpresa ⚠️ siempre aparecen problemas de último minuto, como usuarios que pueden registrarse sin proporcionar una dirección de correo electrónico válida.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flm4t8obfr2dyuq2ugh1f.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flm4t8obfr2dyuq2ugh1f.gif" alt="Pánico!" width="480" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aquí es donde entran en juego las pruebas unitarias, un salvavidas para los desarrolladores. En lugar de esperar hasta el final, las pruebas unitarias se hacen a lo largo del proceso de desarrollo. Básicamente, se prueban pedacitos de código, como funciones o métodos, para asegurarse de que funcionen correctamente.&lt;/p&gt;

&lt;p&gt;Volviendo a nuestro ejemplo del registro de usuarios, con pruebas unitarias, podríamos haber detectado el error antes. Hubiéramos creado una prueba que verifica si la dirección de correo electrónico es válida o no. Si la prueba falla, sabemos que hay un problema en esa parte del código y podemos arreglarlo de inmediato. &lt;/p&gt;

&lt;p&gt;¡No más sorpresas de último minuto!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9nn3g4guwnmzet5wzw9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9nn3g4guwnmzet5wzw9.gif" alt="Alivio!" width="500" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Las pruebas unitarias no solo nos ayudan a encontrar errores antes, sino que también facilitan la identificación de la causa raíz. De esta forma, se reducen la cantidad de errores que llegan al producto final, ya que en ocasiones estos errores pueden escaparse incluso en la fase de pruebas.&lt;/p&gt;

&lt;h2&gt;
  
  
  La Pirámide de Testing
&lt;/h2&gt;

&lt;p&gt;Es importante conocer la pirámide de Testing, ya que en base a esta podemos determinar factores como la rapidez de ejecución, costo, volumen y confiabilidad. Esta pirámide se compone principalmente de las pruebas de interfaz de usuario, pruebas de integración y pruebas unitarias.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk57ey51ncrh4rcnzuhw1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk57ey51ncrh4rcnzuhw1.png" alt="Pirámide de pruebas" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unit Test: 

&lt;ul&gt;
&lt;li&gt;Prueba la unidad de la aplicación sin dependencias externas. &lt;/li&gt;
&lt;li&gt;Son rápidas pero no dan tanta confiabilidad.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Integration Test: 

&lt;ul&gt;
&lt;li&gt;Prueba la aplicación con dependencias externas. &lt;/li&gt;
&lt;li&gt;Son lentas pero dan más confiabilidad.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;End to end Test:

&lt;ul&gt;
&lt;li&gt;Prueba toda la aplicación desde la interfaz de usuario.&lt;/li&gt;
&lt;li&gt;Son muy lentas pero dan muchísima confiabilidad.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Como puedes ver las pruebas unitarias son la base de la pirámide de pruebas y al ser componentes individuales aislados, son ejecutadas rápidamente. En caso de que se encuentren errores en este tipo de pruebas, la corrección del mismo es menos costoso para el proyecto ya que sería detectado en la fase de desarrollo y no en un ambiente productivo o de pruebas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Con dependencias externas nos referimos a base de datos, web services, APIs, cola de mensajes, entre otros.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ¿Qué es un Unit Test?
&lt;/h2&gt;

&lt;p&gt;Un Unit Test, o prueba unitaria, es una técnica de prueba en el desarrollo de software que se enfoca en probar unidades individuales de código, como funciones, métodos o clases, de manera aislada. El objetivo principal es verificar que cada unidad de código funcione correctamente por sí misma, independientemente de su integración con el resto del sistema.&lt;/p&gt;

&lt;p&gt;Básicamente es un porción de código para probar de porción de código.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Existen Frameworks o librerías para hacer Unit Testing en diferentes lenguajes de programación:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;XUnit y NUnit para .NET&lt;/li&gt;
&lt;li&gt;JUnit para Java&lt;/li&gt;
&lt;li&gt;Jest y Cypress para Javascript&lt;/li&gt;
&lt;li&gt;Unittest para Python&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ten en cuenta que no todo el código debe ser probado. Algunos ejemplos de que debe probarse:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Métodos públicos.&lt;/li&gt;
&lt;li&gt;Funciones de tipo query o comandos.&lt;/li&gt;
&lt;li&gt;Cada ruta de ejecución que puede tomar la función.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Por otro lado, no debería ser probado:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Métodos privados, ya que estos se prueban implícitamente dentro de los públicos.&lt;/li&gt;
&lt;li&gt;Features del lenguaje.&lt;/li&gt;
&lt;li&gt;Código de terceros como librerías.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Beneficios del Unit Testing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Garantizar que el código haga lo que se supone que debe hacer.&lt;/li&gt;
&lt;li&gt;Generar código robusto.&lt;/li&gt;
&lt;li&gt;Mejorar la calidad de código productivo.&lt;/li&gt;
&lt;li&gt;Permiten hacer Test Driven Development&lt;/li&gt;
&lt;li&gt;Detección temprana de errores&lt;/li&gt;
&lt;li&gt;Facilita el mantenimiento de código&lt;/li&gt;
&lt;li&gt;Fomenta un diseño desacoplado&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Estructura de un Unit Test
&lt;/h2&gt;

&lt;p&gt;Un Unit Test generalmente sigue una estructura sencilla pero poderosa. Tiene tres pasos básicos, el famoso AAA: Arrange (Preparación), Act (Acción) y Assert (Verificación).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arrange: Inicializamos variables u objetos necesarios para la prueba.&lt;/li&gt;
&lt;li&gt;Act: Invocamos o llamamos el método que queremos probar.&lt;/li&gt;
&lt;li&gt;Assert: Verificar que el valor obtenido sea o no valor esperado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para este ejemplo, usaremos el popular de programación FizzBuzz. De forma resumida, si un número es divisible por 3 imprime Fizz, si es divisible por 5 imprime Buzz y si lo es por 3 y 5 a la vez, imprime FizzBuzz, de lo contrario imprime el número.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;En estos ejemplos, trato de usar lo menos posible las herramientas que ofrece xUnit para que se pueda aplicar a cualquier tecnología.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Creemos la prueba unitaria para validar la correcta implementación de nuestro método siguiendo la estrategia AAA.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TestFixture&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Tests&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;FizzBuzzTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoEsperado&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numeroEntrada&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ServiceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Act&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoObtenido&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;That&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoObtenido&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Is&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EqualTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoEsperado&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;FizzTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoEsperado&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numeroEntrada&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ServiceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Act&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoObtenido&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;That&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoObtenido&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Is&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EqualTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoEsperado&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;BuzzTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoEsperado&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numeroEntrada&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ServiceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Act&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoObtenido&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;That&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoObtenido&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Is&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EqualTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoEsperado&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;NumberTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoEsperado&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"7"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numeroEntrada&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ServiceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Act&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoObtenido&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numeroEntrada&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;That&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoObtenido&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Is&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EqualTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoEsperado&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;En ocasiones puede haber más de un paso en una misma línea de código.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Técnicas de Naming
&lt;/h2&gt;

&lt;p&gt;El arte de nombrar nuestras pruebas es como elegir nombres para nuestras mascotas. En el caso de Unit Testing, queremos que los tests sean claros y descriptivos. Sin embargo, esto depende de la convención que elija el equipo de Desarrollo en el proyecto.&lt;/p&gt;

&lt;p&gt;Mi favorito cumple con la siguiente nomenclatura:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Para el caso de un proyecto: &lt;strong&gt;[Nombre de proyecto].UnitTests&lt;/strong&gt;. Por ejemplo, si el proyecto se llama ApiFly, el proyecto de Unit Test se llamará &lt;strong&gt;ApiFly.UnitTests&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Para el caso de las clases: &lt;strong&gt;[Nombre de clase]Tests&lt;/strong&gt;. Por ejemplo, si la clase se llama ServiceTour, la clase de Unit Testing se llamará &lt;strong&gt;ServiceTourTests&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Para el caso de los métodos: &lt;strong&gt;[Nombre del método]_[Escenario]_[Valor esperado]&lt;/strong&gt;. Por ejemplo, si el método se llama ValidateFlightDate, el método de Unit Testing se llamará &lt;strong&gt;ValidateFlightDate_DateBeforeToday_ReturnFalse&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TestFixture&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ServiceFizzBuzzTests&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Calculate_WhenIsMultipleThreeAndFive_ReturnFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoEsperado&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numeroEntrada&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ServiceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Act&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoObtenido&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;That&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoObtenido&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Is&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EqualTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoEsperado&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Calculate_WhenIsMultipleThree_ReturnFizz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoEsperado&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numeroEntrada&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ServiceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Act&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoObtenido&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;That&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoObtenido&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Is&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EqualTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoEsperado&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Calculate_WhenIsMultipleFive_ReturnBuzz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoEsperado&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numeroEntrada&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ServiceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Act&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoObtenido&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;That&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoObtenido&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Is&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EqualTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoEsperado&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Calculate_WhenIsMultipleThreeAndFive_ReturnFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoEsperado&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"7"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numeroEntrada&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ServiceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Act&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resultadoObtenido&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceFizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numeroEntrada&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;That&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoObtenido&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Is&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EqualTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultadoEsperado&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Otros desarrolladores prefieren la siguiente nomenclatura:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Para el caso de un proyecto: Agregar ".Tests". Por ejemplo, si el proyecto se llama ECommerce, el proyecto Unit Testing se llamaría ECommerce.Tests.&lt;/li&gt;
&lt;li&gt;Para el caso de las clases: Agregar "Should". Por ejemplo, si la clase se llama CatalogService, la clase de Unit Testing se llamaria CatalogServiceShould.&lt;/li&gt;
&lt;li&gt;Para el caso de los métodos: Se nombre con lo que debe retornar bajo determinado escenario. Por ejemplo, si el método nos devuelve true si existe algún producto en Stock, sería llamado Return_True_Exists_Stock().&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Existen muchas otras más, aunque estas son las más comunes.&lt;/p&gt;

&lt;p&gt;Si estas en un equipo, deberás mantener la convención que elijan o que ya este establecida para mantener un estándar.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es un mock?
&lt;/h2&gt;

&lt;p&gt;Un mock es como un actor de cine que interpreta a alguien más en una película. En el Unit Testing, es un objeto que simula ser una dependencia externa de nuestra unidad de código. Por ejemplo, si nuestra función depende de una API, en lugar de llamar a la API real en las pruebas, usamos un mock que actúa como si fuera la API. Los mocks nos permiten remover dependencias externas y hacer nuestras pruebas más controladas y predecibles.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Algunas librerías para hacer mocks en nuestras pruebas unitarias:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Moq y NSubstitute para .NET&lt;/li&gt;
&lt;li&gt;Mockito y EasyMock para Java&lt;/li&gt;
&lt;li&gt;Jest para Javascript&lt;/li&gt;
&lt;li&gt;Unittest.mock para Python&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ¿Qué es el Code Coverage?
&lt;/h2&gt;

&lt;p&gt;El Code Coverage, o cobertura de código, es como una radiografía de nuestro código. Nos muestra cuántas partes han sido cubiertas por nuestras pruebas unitarias.&lt;/p&gt;

&lt;p&gt;Por lo tanto, el Code Coverage nos ayuda a evaluar qué tan bien hemos probado nuestro código, identificando las partes que aún no hemos tocado. Una alta cobertura de código nos da la confianza de que estamos cubriendo la mayoría de los rincones de nuestro software.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Es poco probable que a medida que el software crezca se tenga una cobertura de 100%. Pero siempre hay que tratar de mantener un alto porcentaje.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Existen muchas herramientas para medir el Code Coverage, algunas integradas al IDE y otras aisladas del editor como Sonarqube que aparte de darte otras métricas de calidad, también te indica la cobertura de código.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recomendaciones para tus pruebas unitarias
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Crea pruebas unitarias cortas y legibles. &lt;/li&gt;
&lt;li&gt;Mantén la independencia en tus pruebas. Para ello, evita utilizar recursos externos y en su defecto usa mocks.&lt;/li&gt;
&lt;li&gt;Si tienes que crear muchos test para un único método, revisa detenidamente el método porque probablemente sea mejor una refactorización.&lt;/li&gt;
&lt;li&gt;Utiliza alguna técnica de Naming en tus pruebas y mantén el mismo durante todo el proyecto.&lt;/li&gt;
&lt;li&gt;Evita duplicación de código en tus pruebas, revisa si puedes crear métodos privados para la reutilización que no generen efectos secundarios.&lt;/li&gt;
&lt;li&gt;Evalúa la cobertura de código en tus proyectos. No es necesario tener un 100% pero de 70% para arriba es aceptable.&lt;/li&gt;
&lt;li&gt;Testear sólo las interfaces públicas.&lt;/li&gt;
&lt;li&gt;No debes crear pruebas tan específicas ni tan generales.&lt;/li&gt;
&lt;li&gt;Crear pruebas basada en el número de caminos que puede tomar tu código. Para esto ten en cuenta las condicionales dentro del método que quieres probar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Espero que te haya servido esta guía sobre Unit Testing y que empieces aplicarlo en tus proyectos 🚀.&lt;/p&gt;

&lt;p&gt;¡Happy coding!💻&lt;/p&gt;

</description>
      <category>programming</category>
      <category>testing</category>
      <category>spanish</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Introducción a xUnit: Una poderosa herramienta para Unit Testing en .NET</title>
      <dc:creator>Manuel Dávila Alarcón</dc:creator>
      <pubDate>Mon, 12 Jun 2023 02:32:51 +0000</pubDate>
      <link>https://dev.to/maadcode/introduccion-a-xunit-una-poderosa-herramienta-para-unit-testing-en-net-34b0</link>
      <guid>https://dev.to/maadcode/introduccion-a-xunit-una-poderosa-herramienta-para-unit-testing-en-net-34b0</guid>
      <description>&lt;p&gt;xUnit es una tecnología muy popular para hacer pruebas unitarias (unit test) en aplicaciones .NET y en este artículo daremos los primeros pasos. &lt;/p&gt;

&lt;p&gt;Esta herramienta se puede usar con C#, F# o Visual Basic. Además, es Open Source, simple y flexible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pasos previos a la configuración de xUnit
&lt;/h2&gt;

&lt;p&gt;Es importante que tengas el &lt;a href="https://dotnet.microsoft.com/en-us/download" rel="noopener noreferrer"&gt;SDK .NET 7&lt;/a&gt; instalado y tu editor de código preferido, en mi caso utilizaré Visual Studio Code. Si ya lo tienes instalado, crea un directorio y desde la terminal ubicate en la ruta de dicho directorio. Luego, ejecuta el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F42uj8sobdsu8ajwe0znb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F42uj8sobdsu8ajwe0znb.jpg" alt="Imagen de ejecución de comando dotnet --version" width="247" height="56"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para poder hacer testing, es necesario tener funcionalidades a probar, pueden ser clases o métodos. Por lo tanto, primero vamos a crear un proyecto simple de biblioteca de clases con el comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet new classlib -n FileModule -o FileModule
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdz25au8tg73p48y085y.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdz25au8tg73p48y085y.jpg" alt="Imagen de ejecución de comando dotnet new classlib -n FileModule -o FileModule" width="800" height="136"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dentro del directorio creado llamado FileModule, creamos una clase llamada FileManager con el siguiente código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;FileModule&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileManager&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;FileManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetFilePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadAllText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetFilePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetFilePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpa9o2tyknngz88kuzzor.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpa9o2tyknngz88kuzzor.jpg" alt="Imagen de la estructura de carpetas y archivos del proyecto FileModule" width="256" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuración inicial: Integrando xUnit en tu proyecto
&lt;/h2&gt;

&lt;p&gt;Una vez finalizado el paso anterior, es momento de crear el proyecto de xUnit para escribir y ejecutar nuestras pruebas unitarias. Para ello puedes ejecutar el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet new xunit -n FileModule.UnitTests -o FileModule.UnitTests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5qpbq01zb8xz7p534i76.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5qpbq01zb8xz7p534i76.jpg" alt="Imagen de ejecución de comando dotnet new xunit -n FileModule.UnitTests -o FileModule.UnitTests" width="800" height="108"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tu solución debería estar de la siguiente forma:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foit9fzt9c89h44aear5g.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foit9fzt9c89h44aear5g.jpg" alt="Imagen de la estructura de carpetas y archivos del proyecto FileModule y FileModule.UnitTests" width="262" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A continuación, vamos agregar la referencia del proyecto FileModule a FileModule.UnitTests para poder crear las pruebas unitarias de los métodos con el comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add FileModule.UnitTests reference FileModule
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhoxbvhbrhax3nhxojhfj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhoxbvhbrhax3nhxojhfj.jpg" alt="Imagen de ejecución de comando dotnet add FileModule reference FileModule.UnitTests" width="800" height="51"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En la clase UnitTest1 que se crea por defecto, colocar el siguiente código con la finalidad de observar la ejecución de una prueba:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;FileModule.UnitTests&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UnitTest1&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Test1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;False&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Las pruebas unitarias no deben retornar valores, es decir deben ser void.&lt;/p&gt;

&lt;p&gt;Para ejecutar las pruebas unitarias del proyecto, debemos colocar el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet test FileModule.UnitTests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgbdmljozq65m7uldyb9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgbdmljozq65m7uldyb9.jpg" alt="Imagen de ejecución de comando dotnet test FileModule.UnitTests" width="800" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Intenta cambiar el false por el true y ejecuta nuevamente el comando, obtendrás una prueba fallida.&lt;/p&gt;

&lt;p&gt;Con esto acabas de realizar tu primera prueba unitaria en xUnit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estructura básica de un test en xUnit
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Atributos
&lt;/h3&gt;

&lt;p&gt;Como observaste en el ejemplo anterior usamos el atributo &lt;strong&gt;Fact&lt;/strong&gt;, el cual sirve para marcar un método como prueba unitaria. Algunos otros atributos más usados:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Theory&lt;/strong&gt;: Se utiliza para marcar un método como una teoría, las cuales son pruebas parametrizadas que se ejecutan con diferentes conjuntos de datos que se pasan a través del atributo InlineData.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;InlineData&lt;/strong&gt;: Se utiliza en combinación con Theory y permite proporcionar datos para pruebas parametrizadas. Puedes pasar valores directamente a través del atributo, como &lt;em&gt;[InlineData(1, "Maad")]&lt;/em&gt;, o usar argumentos de tipo simple, como &lt;em&gt;[InlineData("MaadCode")]&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MemberData&lt;/strong&gt;: Se utiliza para pasar datos a una teoría desde una propiedad estática o un campo en la misma clase de prueba o en una clase externa.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Aserciones
&lt;/h3&gt;

&lt;p&gt;Las aserciones sirven para verificar el comportamiento esperado en las pruebas unitarias. Algunos assert más comunes en xunit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Assert.Equal(expected, actual): Esta aserción verifica si dos valores son iguales. Es útil para comparar el valor esperado con el valor real obtenido durante la prueba.&lt;/li&gt;
&lt;li&gt;Assert.True(condition): Comprueba si una condición es verdadera. Se utiliza para validar expresiones booleanas y asegurarse de que se cumplan ciertas condiciones en una prueba.&lt;/li&gt;
&lt;li&gt;Assert.False(condition): Comprueba si una condición es falsa. Al igual que Assert.True(), se utiliza para validar expresiones booleanas y asegurarse de que no se cumplan ciertas condiciones en una prueba.&lt;/li&gt;
&lt;li&gt;Assert.Null(object): Verifica si un objeto es nulo. Se utiliza para asegurarse de que un objeto esperado no tenga ningún valor asignado.&lt;/li&gt;
&lt;li&gt;Assert.NotNull(object): Comprueba si un objeto no es nulo. Es útil para asegurarse de que un objeto esperado tenga un valor asignado.&lt;/li&gt;
&lt;li&gt;Assert.Throws(() =&amp;gt; { ... }): Verifica si se lanza una excepción durante la ejecución de una acción determinada. Se utiliza para asegurarse de que un código específico genere una excepción esperada.&lt;/li&gt;
&lt;li&gt;Assert.InRange(actual, min, max): Comprueba si un valor se encuentra dentro de un rango determinado. Es útil para validar que un resultado se encuentre en un rango específico.&lt;/li&gt;
&lt;li&gt;Assert.Collection(expectedCollection, actualCollection): Verifica si dos colecciones contienen los mismos elementos en el mismo orden. Se utiliza para comparar dos colecciones y asegurarse de que sean idénticas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Es momento de aplicarlo a nuestra prueba. Para eso debemos renombrar el UnitTest1 por FileModuleTest y Test1 por ReadFile_ExistingFile_ReturnsFileContent con el siguiente código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;FileModule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;FileModule.UnitTests&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileModuleTest&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ReadFile_ExistingFile_ReturnsFileContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"TestDirectoryFiles"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileNameOriginal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"prueba.txt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Unit Testing with xUnit!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fileNameOriginal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAllText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"prueba.txt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;FileManager&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Act&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ReadFile_FileNameIsNull_throwArgumentException&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"TestDirectoryFiles"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileNameOriginal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"prueba.txt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Unit Testing with xUnit!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fileNameOriginal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAllText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;FileManager&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Act y Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Throws&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ReadFile_FileNameIsEmpty_throwArgumentException&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"TestDirectoryFiles"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileNameOriginal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"prueba.txt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Unit Testing with xUnit!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fileNameOriginal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAllText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;FileManager&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Act y Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Throws&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ReadFile_FileNameIsWhiteSpace_throwArgumentException&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"TestDirectoryFiles"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Unit Testing with xUnit!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileNameOriginal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"prueba.txt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fileNameOriginal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAllText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;FileManager&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Act y Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Throws&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aquí estamos aplicando la estrategia triple A (Arrange, Act, Assert) y la técnica de Naming de &lt;em&gt;MethodName_Scenario_ExpectedBehaviour&lt;/em&gt; para el nombrado de nuestras pruebas.&lt;/p&gt;

&lt;p&gt;Sin embargo, este código esta realizando la misma configuración previa en cada test, el cual consiste en crear el directorio y el archivo con el texto. Por lo tanto, eso lo podemos realizar en el constructor. En otras bibliotecas como NUNit tendrías que usar el atributo SetUp.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;FileModule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;FileModule.UnitTests&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileModuleTest&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_directory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"TestDirectoryFiles"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;FileModuleTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"prueba.txt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Unit Testing with xUnit!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_directory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAllText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ReadFile_ExistingFile_ReturnsFileContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;contentExpected&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Unit Testing with xUnit!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"prueba.txt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;FileManager&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Act&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contentExpected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ReadFile_FileNameIsNull_throwArgumentException&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;FileManager&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Act y Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Throws&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ReadFile_FileNameIsEmpty_throwArgumentException&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;FileManager&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Act y Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Throws&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ReadFile_FileNameIsWhiteSpace_throwArgumentException&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;FileManager&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Act y Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Throws&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ReadFile_NonExistentFile_ReturnEmptyString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"otherfile.txt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;FileManager&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Act&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora ejecuta el comando&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;dotnet test FileModule.UnitTests&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 en la consola y comprueba que pasen todos los tests.&lt;/p&gt;

&lt;p&gt;Ten en cuenta que no sólo se prueban los métodos que retornan un tipo de dato. Por lo tanto, te reto a crear las pruebas unitarias para el método CreateFile.&lt;/p&gt;
&lt;h2&gt;
  
  
  xUnit para diferentes casos de prueba
&lt;/h2&gt;

&lt;p&gt;Como pudiste ver, en muchas de nuestras pruebas unitarias se espera que se lance una Excepción. Para ello, podemos usar los atributos Theory e InlineData para agrupar casos de prueba que tienen el mismo comportamiento esperado. El código quedaría de la siguiente forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;FileModule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;FileModule.UnitTests&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileModuleTest&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_directory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"TestDirectoryFiles"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;FileModuleTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"prueba.txt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Unit Testing with xUnit!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_directory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAllText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ReadFile_ExistingFile_ReturnsFileContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;contentExpected&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Unit Testing with xUnit!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"prueba.txt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;FileManager&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Act&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contentExpected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Theory&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;InlineData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;InlineData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;InlineData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ReadFile_FileNameIsNullOrWhiteSpace_throwArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="n"&gt;FileManager&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Act y Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Throws&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ReadFile_NonExistentFile_ReturnEmptyString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"otherfile.txt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;FileManager&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_directory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Act&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Consideraciones
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Utiliza estrategias como triple A (Arrange, Act, Assert) para tus pruebas unitarias.&lt;/li&gt;
&lt;li&gt;Debes tener una técnica de Naming para tus clases y métodos de prueba. Algunos prefieren nombrar a sus clases de prueba con la palabra &lt;em&gt;Should&lt;/em&gt; al final, en nuestro caso usamos &lt;em&gt;Test&lt;/em&gt;. Lo importante es mantener dicha técnica con todo el equipo y en todo el proyecto.&lt;/li&gt;
&lt;li&gt;Debes identificar lo que debes probar y lo que no.&lt;/li&gt;
&lt;li&gt;Tus pruebas unitarias deben ser cortas y deben probar sólo una pequeña porción de funcionalidad.&lt;/li&gt;
&lt;li&gt;Existen herramientas en los IDE como Visual Studio, que facilitan la ejecución, depuración y visualización de pruebas unitarias.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Espero que este post te sea de utilidad y lo hayas disfrutado. &lt;br&gt;
¡Happy coding!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>dotnet</category>
      <category>xunit</category>
      <category>spanish</category>
    </item>
    <item>
      <title>Descubre cómo utilizar variables en C# para optimizar tu código: Guía completa</title>
      <dc:creator>Manuel Dávila Alarcón</dc:creator>
      <pubDate>Thu, 27 Apr 2023 22:17:01 +0000</pubDate>
      <link>https://dev.to/maadcode/descubre-como-utilizar-variables-en-c-para-optimizar-tu-codigo-guia-completa-3n4</link>
      <guid>https://dev.to/maadcode/descubre-como-utilizar-variables-en-c-para-optimizar-tu-codigo-guia-completa-3n4</guid>
      <description>&lt;p&gt;Si estás interesado en el mundo de la programación, seguramente has escuchado hablar de C#. Este lenguaje de programación es muy popular y es utilizado por muchas empresas. En este artículo, te explicaré de manera sencilla qué son las variables en C# y cómo puedes utilizarlas para crear programas geniales. ¡Empecemos!&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducción a las variables en C#: ¿qué son y para qué sirven?
&lt;/h2&gt;

&lt;p&gt;Cuando se programa en C#, se utilizan variables para almacenar temporalmente datos que serán utilizados en el programa. Estas variables pueden guardar diferentes tipos de datos y su valor puede cambiar a lo largo del programa.&lt;/p&gt;

&lt;p&gt;Una variable es una zona de memoria reservada en la computadora que tiene un nombre y un tipo de dato. El nombre de la variable se utiliza para hacer referencia en el programa, y el tipo de dato indica qué tipo de información se almacenará en ella. Al asignar un valor a una variable, se guarda el valor en la memoria reservada para esa variable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp690krp2ybanfanjfbv3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp690krp2ybanfanjfbv3.png" alt="Funcionamiento de una variable" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Posiblemente en el colegio hayas llevado ecuaciones donde tenias que encontrar el valor de una variable X. Por ejemplo, en la ecuación &lt;em&gt;y = 3x + 5&lt;/em&gt;, la variable X representa un valor desconocido que debe ser determinado a partir de otros datos.&lt;/p&gt;

&lt;p&gt;De manera similar, en programación, las variables se utilizan para almacenar valores que pueden ser desconocidos al principio pero que deben ser determinados a lo largo del programa. Por ejemplo, una variable edad podría representar la edad de un usuario de un programa, que es desconocida al principio pero que se determina a partir de los datos que proporciona el usuario.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tipos de variables en C#: enteros, decimales, booleanos y más.
&lt;/h2&gt;

&lt;p&gt;C# es un lenguaje de programación fuertemente tipado, lo que significa que cada variable debe tener un tipo de dato definido en el momento de su declaración. Los tipos de variables más comunes en C# son los siguientes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tipo de dato&lt;/th&gt;
&lt;th&gt;Descripción&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Representa un valor booleano, que puede ser verdadero o falso&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;byte&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Representa un número entero sin signo de 8 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sbyte&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Representa un número entero con signo de 8 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;char&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Representa un carácter Unicode de 16 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;decimal&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Representa un número decimal con una precisión de 28-29 dígitos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;double&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Representa un número decimal de punto flotante de 64 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;float&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Representa un número decimal de punto flotante de 32 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;int&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Representa un número entero con signo de 32 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uint&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Representa un número entero sin signo de 32 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;long&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Representa un número entero con signo de 64 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ulong&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Representa un número entero sin signo de 64 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;object&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Representa cualquier tipo de objeto&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;short&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Representa un número entero con signo de 16 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ushort&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Representa un número entero sin signo de 16 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;string&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Representa una secuencia de caracteres Unicode&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Si bien C# es un lenguaje fuertemente tipado, podemos crear variables con un tipo dinámico utilizando la palabra reservada dynamic como tipo de dato. A continuación, un ejemplo de como podemos asignar a una variable diferente tipos de datos con dynamic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;dynamic&lt;/span&gt; &lt;span class="n"&gt;variableConTipadoDinamico&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;variableConTipadoDinamico&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Aquí es un String&lt;/span&gt;
&lt;span class="n"&gt;variableConTipadoDinamico&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;variableConTipadoDinamico&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Aquí es un Int&lt;/span&gt;
&lt;span class="n"&gt;variableConTipadoDinamico&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;variableConTipadoDinamico&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Aquí es un Boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Declaración y asignación de variables en C#: cómo empezar a usarlas.
&lt;/h2&gt;

&lt;p&gt;En C#, declarar y asignar variables es una tarea muy sencilla. Para declarar una variable, se utiliza la sintaxis &lt;em&gt;tipoDeDato nombreDeVariable;&lt;/em&gt;. Mientras que para asignar se utiliza &lt;em&gt;nombreDeVariable = valor;&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;edad&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Esto es una declaración&lt;/span&gt;
&lt;span class="n"&gt;edad&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Esto es una asignación&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;¿Y si queremos declara y asignar al mismo tiempo? Podemos hacerlo en la misma línea de la siguiente forma :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;edad&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Declaración y asignación en la misma línea&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sin embargo, existe otra forma para crear variables cuando declaramos y asignamos su valor en la misma línea, utilizando la palabra reservada var. Esto nos ayuda a declarar variables con el tipo de dato implícito, es decir sin especificar el tipo de dato a la variable, ya que tomará el tipo de dato que se le asigne.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Declaración explícita&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Maad"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// String&lt;/span&gt;

&lt;span class="c1"&gt;// Declaración implícita&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fullname&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Maadcode"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fullname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// String&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;edad&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;21&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;edad&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Int&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tener en cuenta que esta forma sólo funciona cuando declaras y asignas en la misma línea, si sólo declaras una variable usando var sin asignarle un valor tendrás un error, ya que el compilador no podrá identificar el tipo de dato.&lt;/p&gt;

&lt;h2&gt;
  
  
  Operaciones con variables en C#: aritméticos, lógicos y de comparación.
&lt;/h2&gt;

&lt;p&gt;En programación, las operaciones con variables son fundamentales. Aquí te mostramos cómo realizar operaciones básicas en C#.&lt;/p&gt;

&lt;p&gt;Operadores Aritméticos : &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operación&lt;/th&gt;
&lt;th&gt;Descripción&lt;/th&gt;
&lt;th&gt;Ejemplo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;+&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Suma dos valores.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int resultado = 5 + 3; // resultado = 8&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Resta dos valores.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int resultado = 7 - 2; // resultado = 5&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Multiplica dos valores.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int resultado = 4 * 6; // resultado = 24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Divide dos valores.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int resultado = 15 / 3; // resultado = 5&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Obtiene el resto de una división.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int resultado = 10 % 3; // resultado = 1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;++&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Aumenta en 1.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int resultado = 1; resultado++; // resultado = 2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reduce en 1.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int resultado = 1; resultado--; // resultado = 0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Operadores Lógicos : &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operación&lt;/th&gt;
&lt;th&gt;Descripción&lt;/th&gt;
&lt;th&gt;Ejemplo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;AND lógico. Devuelve &lt;code&gt;true&lt;/code&gt; si ambas expresiones son verdaderas.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool resultado = (true &amp;amp;&amp;amp; true); // resultado = true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;||&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OR lógico. Devuelve &lt;code&gt;true&lt;/code&gt; si al menos una de las expresiones es verdadera.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool resultado = (true || false); // resultado = true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;!&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;NOT lógico. Niega la expresión dada.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool resultado = !(true); // resultado = false&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Operadores de comparación :&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operación&lt;/th&gt;
&lt;th&gt;Descripción&lt;/th&gt;
&lt;th&gt;Ejemplo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;==&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Igualdad. Devuelve &lt;code&gt;true&lt;/code&gt; si ambas expresiones son iguales.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool resultado = (10 == 10); // resultado = true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;!=&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Desigualdad. Devuelve &lt;code&gt;true&lt;/code&gt; si ambas expresiones son diferentes.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool resultado = (10 != 15); // resultado = true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Menor que. Devuelve &lt;code&gt;true&lt;/code&gt; si el valor de la izquierda es menor al de la derecha.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool resultado = (10 &amp;lt; 15); // resultado = true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Mayor que. Devuelve &lt;code&gt;true&lt;/code&gt; si el valor de la izquierda es mayor al de la derecha.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool resultado = (15 &amp;gt; 10); // resultado = true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;=&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Menor o igual que. Devuelve &lt;code&gt;true&lt;/code&gt; si el valor de la izquierda es menor o igual al de la derecha.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool resultado = (15 &amp;lt;= 15); // resultado = true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;gt;=&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Mayor o igual que. Devuelve &lt;code&gt;true&lt;/code&gt; si el valor de la izquierda es mayor o igual al de la derecha.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool resultado = (10 &amp;gt;= 10); // resultado = true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Reglas y convenciones para nombrar variables en C#: buenas prácticas a tener en cuenta.
&lt;/h2&gt;

&lt;p&gt;Cuando estás programando en C#, es muy importante nombrar tus variables de forma clara y concisa para que otros desarrolladores puedan entender fácilmente el código. Para hacerlo bien, hay algunas reglas y convenciones que debes seguir.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Utilizar nombres descriptivos
&lt;/h3&gt;

&lt;p&gt;Es recomendable utilizar nombres de variables que sean descriptivos y que den una idea clara del propósito de la variable. Esto ayudará a otros desarrolladores a entender rápidamente lo que la variable representa, lo que puede mejorar la legibilidad del código.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Supongamos que queremos aplicar un descuento de 5% a un producto cuando su precio es mayor a 1200&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dscto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;prod&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1500d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Usamos la letra d al final del número para indicar que es un double, sino lo agregas creara la variable tipo int, la otra opción es que indiques explicitamente que es un double&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prod&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prod&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prod&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dscto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prod&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Con el código anterior no es claro a que se refiere cada variable, tendríamos que leer todo el código y debuggear para entender, lo cual tomaría tiempo innecesario. Entonces, ¿cómo podemos hacer este código más legible? Veamos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;porcentajeDescuento&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;precioDeProducto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1500d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;totalAPagar&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;precioDeProducto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;precioDeProducto&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;totalAPagar&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;precioDeProducto&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;porcentajeDescuento&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;totalAPagar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ya quedo mucho mejor. Sin embargo, ese número 1200 que se encuentra en la condicional, es número mágico y debemos evitarlo. Un número mágico es un valor que representa algún dato significativo para el negocio pero es posible que otro desarrollador nuevo no comprenda dicho valor si no tiene contexto.&lt;/p&gt;

&lt;p&gt;Modifiquemos el código para evitar ese número mágico.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;PRECIO_APLICABLE_DESCUENTO&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;porcentajeDescuento&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;precioDeProducto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1500d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;totalAPagar&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;precioDeProducto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;precioDeProducto&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;PRECIO_APLICABLE_DESCUENTO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;totalAPagar&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;precioDeProducto&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;porcentajeDescuento&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;totalAPagar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Posiblemente vas a tener que crear variables de tipo boolean, es decir que sólo puede ser true o false. En ese caso, puedes usar un truco para verificar si es legible, para ello debes crear una pregunta de la siguiente forma : ¿[nombre de variable]? y la respuesta sólo puede ser Sí/No.&lt;/p&gt;

&lt;p&gt;¿No quedó claro? Siguiendo el código de ejemplo anterior, supongamos que creaste una variable boolean llamada &lt;em&gt;aDescontar&lt;/em&gt; entonces la pregunta que formularias sería &lt;em&gt;¿A descontar? Sí/No&lt;/em&gt;. Como puedes ver no es muy claro, por lo tanto hay que buscar otro nombre que sea más entendible, por ejemplo, si lo llamamos &lt;em&gt;aplicaDescuento&lt;/em&gt;, tendríamos la siguiente pregunta &lt;em&gt;¿Aplica descuento? Sí/No&lt;/em&gt;. Este último es mucho más entendible, por lo tanto ya encontraste el nombre ideal para tu variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;PRECIO_APLICABLE_DESCUENTO&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;descuento&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;precioDeProducto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1500d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;totalAPagar&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;precioDeProducto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;aplicaDescuento&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;precioDeProducto&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;PRECIO_APLICABLE_DESCUENTO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Nuestra variable legible&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aplicaDescuento&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;totalAPagar&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;precioDeProducto&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;descuento&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;totalAPagar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Utilizar nombres en inglés
&lt;/h3&gt;

&lt;p&gt;Aunque no es obligatorio, es recomendable utilizar nombres de variables en inglés, ya que es el idioma que se utiliza comúnmente en la documentación y en la comunidad de desarrollo de software.&lt;/p&gt;

&lt;p&gt;Sin embargo, otro motivo por el que recomiendo usar variables en inglés (si es que el proyecto en el que estas te lo permite), es porque crear nombres de variables es mucho más sencillo en este idioma, ya que el español tiene muchas reglas gramaticales que eventualmente tendrás problema con alguna palabra o letras como la ñ.&lt;/p&gt;

&lt;p&gt;Por otro lado, los nombres de las clases o métodos que usarás de librerías nativas de la tecnología que estés usando, están en inglés, por lo que terminarás con un proyecto en spanglish.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Técnicas de Naming para mejorar la legibilidad
&lt;/h3&gt;

&lt;p&gt;Es posible que te encuentres con que una palabra no es suficientemente descriptivo para tu variable, para ello existen las técnicas de Naming, las más populares son: Camel Case, Pascal Case, Snake Case, Kebab Case. En los ejemplos anteriores hemos hecho uso de estas.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Técnica de Naming&lt;/th&gt;
&lt;th&gt;Descripción&lt;/th&gt;
&lt;th&gt;Ejemplo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Camel Case&lt;/td&gt;
&lt;td&gt;Escribir palabras juntas sin espacios, cada palabra adicional comienza con mayúscula.&lt;/td&gt;
&lt;td&gt;ejemploDeCamelCase&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pascal Case&lt;/td&gt;
&lt;td&gt;Escribir palabras juntas sin espacios, cada palabra comienza con mayúscula.&lt;/td&gt;
&lt;td&gt;EjemploDePascalCase&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snake Case&lt;/td&gt;
&lt;td&gt;Escribir palabras separadas por guiones bajos.&lt;/td&gt;
&lt;td&gt;ejemplo_de_snake_case&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Ejemplo de variables escritas en Camel Case&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;contadorDeVotos&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;textoDeError&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"No se pudo cargar el archivo."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Ejemplo de variables escritas en Pascal Case&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Edad&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;27&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;NombreCompleto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Ana Garcia"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Ejemplo de variables escritas en Snake Case, usando principalmente en Constantes&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;PRECIO_APLICABLE_DESCUENTO&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;CODIGO_POR_DEFECTO&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;999&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Consejos para trabajar con variables en C
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Si vas a realizar la misma operación en diferentes partes del mismo método, es mejor &lt;strong&gt;crear una variable local que guarde el resultado de esa operación&lt;/strong&gt;. De esta manera, se evita realizar la operación varias veces y se mejora el rendimiento del código. Además, el uso de una variable local puede hacer que el código sea más legible y fácil de entender para otros desarrolladores que puedan trabajar en el mismo proyecto.&lt;/p&gt;

&lt;p&gt;Utiliza tipos de datos adecuados para los valores que vas a almacenar. Por ejemplo, si necesitas almacenar números enteros pequeños como la edad de un usuario, utiliza tipos &lt;strong&gt;byte en lugar de int&lt;/strong&gt;. Esto puede ahorrar espacio en memoria y mejorar el rendimiento.&lt;/p&gt;

&lt;p&gt;Usa el modificador &lt;strong&gt;const&lt;/strong&gt; para crear constantes, es decir valores que no cambian en tiempo de ejecución. Esto permite al compilador optimizar el código eliminando la necesidad de asignar memoria dinámica para estas variables.&lt;/p&gt;

&lt;p&gt;Utiliza &lt;strong&gt;nombres descriptivos&lt;/strong&gt; y en inglés para tus variables que sean fáciles de leer para otros desarrolladores.&lt;/p&gt;

&lt;p&gt;Crea estándares en tus proyectos usando las &lt;strong&gt;técnicas de Naming&lt;/strong&gt; para una mejor legibilidad y homogeneidad. De esta forma se mantiene el mismo formato en los nombres de variables en todo el proyecto.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Espero que este post te sea de utilidad y lo hayas disfrutado. &lt;br&gt;
¡Happy coding!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>programming</category>
      <category>spanish</category>
    </item>
  </channel>
</rss>
