0Pricing
C# Academy · Lezione

Progettazione statica e di istanza

Decida quando è appropriato utilizzare uno stato statico.

Progettazione statica e di istanza è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.

Una scelta progettuale

Scegliere tra static e instance è una decisione progettuale. La domanda fondamentale è: il comportamento dipende dallo stato del singolo oggetto o soltanto dai suoi input?

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));
    }
}

Usi static per la logica senza stato

Se un metodo non ha bisogno di campi dell'istanza e si limita a trasformare gli input, lo renda static. Gli helper matematici e i formattatori sono esempi tipici.

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");
    }
}

Usi le istanze per lo stato

Se il comportamento dipende da dati che variano da un oggetto all'altro, usi un'instance. Ogni oggetto conserva il proprio stato.

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);
    }
}

Lo stato condiviso è uno stato globale

Un campo statico è di fatto globale. Può causare bug difficili da individuare quando molte parti del programma lo leggono e lo modificano. Preferisca lo stato dell'istanza quando ogni utente ha bisogno della propria 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);
    }
}

Testabilità

I metodi statici puri sono facili da testare: stesso input, stesso risultato. Lo stato statico mutabile, invece, si trasferisce da un test all'altro e li rende fragili.

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 per gli helper factory

I metodi factory statici sono un modo pulito per creare istanze configurate con un nome descrittivo.

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);
    }
}

Eviti static solo per evitare new

Non renda tutto static solo per evitare di creare oggetti. Se un tipo rappresenta un'entità dotata di stato, le istanze mantengono tale stato isolato e sicuro.

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);
    }
}

Usare entrambi nel modo giusto

Molte classi usano membri statici per costanti o contatori condivisi e membri di istanza per i dati propri di ogni oggetto. Questa combinazione è del tutto idiomatica.

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);
    }
}

Attenzione alla concorrenza

Più thread possono accedere contemporaneamente allo stato statico condiviso, con il rischio di condizioni di gara. Lo stato dell'istanza confinato a un singolo thread è più sicuro per impostazione predefinita.

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 semplice regola pratica

Static = comportamento che appartiene al tipo e non usa lo stato di un singolo oggetto. Instance = comportamento che legge o modifica un oggetto specifico. In caso di dubbio, preferisca l'istanza per tutto ciò che gestisce uno stato.

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));
    }
}

In sintesi

Una buona progettazione separa gli helper senza stato (static) dai modelli con stato (instance), mantenendo intenzionalmente al minimo lo stato mutabile condiviso.

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));
    }
}

Verifica rapida

Verifichi la Sua comprensione della progettazione static rispetto a instance.

Riepilogo

Scelga static per la logica senza stato che dipende soltanto dagli input, come helper, factory e costanti, e instance per il comportamento legato allo stato di ogni oggetto. Lo stato statico mutabile è di fatto globale, più difficile da testare e soggetto a bug di concorrenza; lo mantenga quindi minimo e intenzionale.

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());
    }
}

Domande Frequenti

La lezione «Progettazione statica e di istanza» è gratuita?

Sì — il testo completo di «Progettazione statica e di istanza» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.

Cosa imparerò in «Progettazione statica e di istanza»?

Decida quando è appropriato utilizzare uno stato statico. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C# Academy?

Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Progettazione statica e di istanza»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C# Academy?

Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Metodi e campi statici
  2. Classi statiche per le utilità
  3. Costanti e campi readonly
  4. Progettazione statica e di istanza
← Torna a C# Academy