C# Academy · leksjon

Statisk kontra instansbasert utforming

Avgjør når statisk tilstand er hensiktsmessig.

Leksjon 4 av 413 trinn

Statisk kontra instansbasert utforming er en gratis leksjon i C# Academy på CoddyKit. Dette er leksjon 4 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i C# Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i C# Academy inneholder totalt 4 leksjoner.

Et designvalg

Å velge mellom static og instance er et designvalg. Det viktigste spørsmålet er om atferden avhenger av tilstand per objekt, eller bare av inndataene.

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

Bruk static for logikk uten tilstand

Hvis en metode ikke trenger noen instansfelt og bare omformer inndata, bør den være static. Matematiske hjelpefunksjoner og formaterere er gode eksempler.

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

Bruk instanser for tilstand

Hvis atferden avhenger av data som varierer fra objekt til objekt, bør du bruke en instans. Hvert objekt har sin egen tilstand.

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

Delt tilstand er global tilstand

Et static-felt er i praksis globalt. Det kan føre til vanskelige feil når mange deler av et program leser og skriver til det. Foretrekk instanstilstand når hver bruker trenger sin egen kopi.

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

Testbarhet

Rene static-metoder er enkle å teste: samme inndata gir samme utdata. Muterbar static-tilstand lekker derimot mellom tester og gjør dem sårbare.

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 for fabrikkhjelpere

Statiske fabrikkmetoder er en ryddig måte å opprette konfigurerte instanser med et beskrivende navn på.

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

Unngå static bare for å slippe new

Ikke gjør alt static bare for å unngå å opprette objekter. Hvis en type modellerer noe som har tilstand, holder instanser denne tilstanden isolert og trygg.

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

Kombiner begge på riktig måte

Mange klasser bruker static-medlemmer for delte konstanter eller tellere og instansmedlemmer for data per objekt. Denne kombinasjonen er helt idiomatisk.

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

Problem med samtidighet

Delt static-tilstand kan aksesseres av flere tråder samtidig, noe som kan føre til kappløpssituasjoner. Instanstilstand som er begrenset til én tråd, er som standard tryggere.

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

En enkel tommelfingerregel

Static = atferd som hører til typen og ikke bruker tilstand per objekt. Instance = atferd som leser eller endrer et bestemt objekt. Når du er i tvil, bør du foretrekke instanser for alt som har tilstand.

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

Slik henger det sammen

Godt design skiller hjelpefunksjoner uten tilstand (static) fra modeller med tilstand (instans), slik at delt, muterbar tilstand holdes bevisst på et minimum.

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

Hurtigsjekk

Test forståelsen din av design med static og instanser.

Oppsummering

Velg static for logikk uten tilstand som bare avhenger av inndata (hjelpefunksjoner, fabrikker, konstanter), og instance for atferd som er knyttet til tilstand per objekt. Muterbar static-tilstand er i praksis global, vanskeligere å teste og utsatt for samtidighetsfeil, så hold den på et minimum og bruk den bevisst.

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 å komme i gang

Lær deg C# med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
93
Leksjoner
346

Ofte stilte spørsmål

Er leksjonen «Statisk kontra instansbasert utforming» gratis?

Ja – hele teksten i «Statisk kontra instansbasert utforming» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av C# Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i C# Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Statisk kontra instansbasert utforming»?

Avgjør når statisk tilstand er hensiktsmessig. Du øver på C# Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med C# Academy?

Ingen tidligere erfaring er nødvendig. C# Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.

Hvor lang tid tar leksjonen «Statisk kontra instansbasert utforming»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne C# Academy-leksjonen?

Ja. Alle C# Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Statiske metoder og felt
  2. Statiske klasser for verktøy
  3. Konstanter og readonly-felt
  4. Statisk kontra instansbasert utforming
← Tilbake til C# Academy