C# Academy · Lección

Diseño estático frente a diseño de instancia

Decida cuándo es adecuado utilizar estado estático.

Lección 4 de 413 pasos

Diseño estático frente a diseño de instancia es una lección gratuita de C# Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C# Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C# Academy incluye 4 lecciones en total.

Una decisión de diseño

Elegir entre static y instance es una decisión de diseño. La pregunta clave es: ¿el comportamiento depende del estado de cada objeto o solo de sus entradas?

using System;

class Program
{
    // Depends only on inputs -> good static method
    static int Max(int a, int b) => a > b ? a : b;

    static void Main()
    {
        Console.WriteLine(Max(3, 8));
    }
}

Utilice static para la lógica sin estado

Si un método no necesita campos de instancia y solo transforma entradas, conviértalo en static. Las funciones auxiliares matemáticas y los formateadores son ejemplos destacados.

using System;

static class Convert2
{
    public static double MilesToKm(double miles) => miles * 1.60934;
}

class Program
{
    static void Main()
    {
        Console.WriteLine(Convert2.MilesToKm(10).ToString("0.0") + " km");
    }
}

Utilice instance para el estado

Si el comportamiento depende de datos que varían según el objeto, utilice una instancia. Cada objeto mantiene su propio estado.

using System;

class Counter
{
    private int _count;
    public void Increment() => _count++;
    public int Value => _count;
}

class Program
{
    static void Main()
    {
        var a = new Counter();
        var b = new Counter();
        a.Increment();
        a.Increment();
        b.Increment();
        Console.WriteLine("a=" + a.Value + ", b=" + b.Value);
    }
}

El estado compartido es estado global

Un campo static es, en la práctica, global. Puede provocar errores sutiles cuando muchas partes de un programa lo leen y escriben. Prefiera el estado de instancia cuando cada usuario necesite su propia copia.

using System;

class BadCart
{
    public static int Items;   // shared by EVERYONE -> usually wrong for a cart
}

class Program
{
    static void Main()
    {
        BadCart.Items++;
        BadCart.Items++;
        Console.WriteLine("All carts share: " + BadCart.Items);
    }
}

Facilidad de prueba

Los métodos static puros son fáciles de probar: misma entrada, misma salida. Sin embargo, el estado mutable static se filtra entre las pruebas y las vuelve frágiles.

using System;

static class Calc
{
    public static int Add(int a, int b) => a + b;   // trivially testable
}

class Program
{
    static void Main()
    {
        Console.WriteLine(Calc.Add(2, 2) == 4 ? "pass" : "fail");
    }
}

static para métodos auxiliares de fábrica

Los métodos de fábrica static son una forma clara de crear instancias configuradas con un nombre descriptivo.

using System;

class Color
{
    public int R, G, B;
    private Color(int r, int g, int b) { R = r; G = g; B = b; }

    public static Color Red() => new Color(255, 0, 0);
    public static Color White() => new Color(255, 255, 255);
}

class Program
{
    static void Main()
    {
        var c = Color.Red();
        Console.WriteLine(c.R + "," + c.G + "," + c.B);
    }
}

Evite usar static solo para omitir new

No convierta todo en static solo para evitar crear objetos. Si un tipo representa algo con estado, las instancias mantienen ese estado aislado y seguro.

using System;

class Player
{
    public string Name;
    public int Health = 100;
    public void TakeDamage(int d) => Health -= d;
}

class Program
{
    static void Main()
    {
        var p1 = new Player { Name = "A" };
        var p2 = new Player { Name = "B" };
        p1.TakeDamage(30);
        Console.WriteLine(p1.Name + ": " + p1.Health + ", " + p2.Name + ": " + p2.Health);
    }
}

Combinar ambos de forma adecuada

Muchas clases utilizan miembros static para constantes o contadores compartidos y miembros de instancia para los datos de cada objeto. Esta combinación es perfectamente idiomática.

using System;

class Invoice
{
    private static int _seq = 1000;
    public readonly int Number;
    public decimal Amount;

    public Invoice(decimal amount)
    {
        Number = _seq++;
        Amount = amount;
    }
}

class Program
{
    static void Main()
    {
        var i1 = new Invoice(50m);
        var i2 = new Invoice(75m);
        Console.WriteLine(i1.Number + " / " + i2.Number);
    }
}

Consideración sobre la concurrencia

Varios hilos pueden acceder al estado static compartido al mismo tiempo, lo que puede provocar condiciones de carrera. El estado de instancia confinado a un solo hilo es más seguro de forma predeterminada.

using System;

class SafeCalc
{
    // No shared mutable state -> naturally thread-safe
    public static long Factorial(int n)
    {
        long result = 1;
        for (int i = 2; i <= n; i++) result *= i;
        return result;
    }
}

class Program
{
    static void Main()
    {
        Console.WriteLine(SafeCalc.Factorial(5));
    }
}

Una regla práctica sencilla

static = comportamiento que pertenece al tipo y no utiliza el estado de cada objeto. instance = comportamiento que lee o cambia un objeto concreto. En caso de duda, prefiera una instancia para todo lo que tenga estado.

using System;

class Temperature
{
    public double Celsius;                                  // instance state
    public static double ToF(double c) => c * 9 / 5 + 32;   // stateless helper
}

class Program
{
    static void Main()
    {
        var t = new Temperature { Celsius = 30 };
        Console.WriteLine(Temperature.ToF(t.Celsius));
    }
}

Unir todas las piezas

Un buen diseño separa las funciones auxiliares sin estado (static) de los modelos con estado (de instancia) y mantiene el estado mutable compartido en un mínimo deliberado.

using System;

static class TaxRules
{
    public static decimal Apply(decimal amount, decimal rate) => amount + amount * rate;
}

class Sale
{
    public decimal Subtotal;
    public decimal Total(decimal rate) => TaxRules.Apply(Subtotal, rate);
}

class Program
{
    static void Main()
    {
        var s = new Sale { Subtotal = 100m };
        Console.WriteLine(s.Total(0.2m));
    }
}

Comprobación rápida

Compruebe su comprensión del diseño static frente al diseño de instancia.

Resumen

Elija static para la lógica sin estado que depende únicamente de las entradas (funciones auxiliares, fábricas y constantes) y instance para el comportamiento vinculado al estado de cada objeto. El estado mutable static es, en la práctica, global, resulta más difícil de probar y puede provocar errores de concurrencia; por eso, manténgalo al mínimo y úselo deliberadamente.

using System;

static class Util { public static int Sq(int n) => n * n; }

class Box { public int Size; public int Area() => Util.Sq(Size); }

class Program
{
    static void Main()
    {
        var box = new Box { Size = 4 };
        Console.WriteLine(box.Area());
    }
}
Gratis para empezar

Aprende C# con un tutor de IA — gratis

Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.

Cursos
93
Lecciones
346

Preguntas frecuentes

¿La lección «Diseño estático frente a diseño de instancia» es gratis?

Sí — el texto completo de «Diseño estático frente a diseño de instancia» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C# Academy, actualiza a CoddyKit PRO. El curso de C# Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Diseño estático frente a diseño de instancia»?

Decida cuándo es adecuado utilizar estado estático. Practicas C# Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar C# Academy?

No se requiere experiencia previa. C# Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Diseño estático frente a diseño de instancia»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de C# Academy?

Sí. Cada lección de C# Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Métodos y campos estáticos
  2. Clases estáticas para utilidades
  3. Constantes y campos readonly
  4. Diseño estático frente a diseño de instancia
← Volver a C# Academy