Dela via


C#-klasser

Tips/Råd

Är du nybörjare på att utveckla programvara? Börja med självstudierna Komma igång först. Du kommer att stöta på klasser när du behöver modellera objekt med beteende och tillstånd.

Har du erfarenhet av ett annat språk? C#-klasser liknar klasser i Java eller C++. Skumma avsnittet objektinitialiserare för C#-specifika mönster och se Records för ett datafokuserat alternativ.

En klass är en referenstyp som definierar en skiss för objekt. När du skapar en variabel av en klasstyp innehåller variabeln en referens till ett objekt på den hanterade heapen. Variabeln innehåller inte själva objektdata. Om du tilldelar en klassvariabel till en annan variabel kopieras referensen, så båda variablerna pekar på samma objekt. Klasser är det vanligaste sättet att definiera anpassade typer i C#. Använd dem när du behöver komplext beteende, arv eller delad identitet mellan referenser.

När du ska använda klasser

Använd en klass när:

  • Typen har komplext beteende eller hanterar föränderligt tillstånd.
  • Du behöver arv för att skapa en basklass med härledda specialiseringar eller för att skapa en härledd typ som utökar en befintlig klass.
  • Instanser representerar en delad identitet, inte objekt som råkar innehålla lika värden. Två referenser till samma objekt bör vara synkroniserade.
  • Typen är stor eller långlivad och drar nytta av heapallokering och referenssemantik.

Deklarera en klass

Definiera en klass med nyckelordet class följt av typnamnet. En valfri åtkomstmodifierare styr synligheten. Standardvärdet är internal. Ange public så att anropare från andra sammansättningar kan använda dina typer.

public class Customer
{
    public string Name { get; set; }

    public Customer(string name) => Name = name;
}

Klasstexten innehåller fält, egenskaper, metoder och händelser, tillsammans kallade klassmedlemmar. Namnet måste vara ett giltigt C# -identifierarnamn.

Skapa objekt

En klass definierar en typ, men det är inte själva objektet. Du skapar ett objekt (en instans av klassen) med nyckelordet new :

var customer = new Customer("Allison");
Console.WriteLine(customer.Name); // Allison

Variabeln customer innehåller en referens till objektet, inte själva objektet. Du kan tilldela flera variabler till samma objekt. Ändringar via en referens visas via den andra:

var c1 = new Customer("Grace");
var c2 = c1; // both variables reference the same object

c2.Name = "Hopper";
Console.WriteLine(c1.Name); // Hopper — c1 sees the change made through c2

Det här beteendet för referensdelning är en skillnad mellan klasser och structs. Med structs kopierar tilldelningen data. Ännu viktigare är att klasser stöder arv. Du kan skapa hierarkier där härledda typer återanvänder och specialiserar beteende från en basklass. Structs kan inte delta i arvshierarkier. Mer information om skillnaden finns i Värdetyper och referenstyper.

Konstruktorer och initialisering

När du skapar en instans vill du att dess fält och egenskaper ska initieras till användbara värden. C# erbjuder flera metoder: fältinitierare, konstruktorparametrar, primära konstruktorer och nödvändiga egenskaper.

Fältinitierare anger ett standardvärde direkt i fältdeklarationen:

public class Container
{
    private int _capacity = 10;
}

Fältinitierare tilldelar ett rimligt standardvärde till ett fält eller en egenskap. Detta skiljer den från följande metoder där anropare kan ange det ursprungliga värdet.

Konstruktorparametrar kräver att anropare anger värden:

public class Container
{
    private int _capacity;

    public Container(int capacity) => _capacity = capacity;
}

Primära konstruktorer (C# 12+) lägger till parametrar direkt i klassdeklarationen. Dessa parametrar är tillgängliga i hela klasstexten:

public class Container(int capacity)
{
    private int _capacity = capacity;
}

Primära konstruktorer och fältinitierare kan fungera tillsammans: fältinitieraren _capacity = capacity använder parametern primary-constructor som värde. Med det här mönstret kan du samla in konstruktorargument i fält med en enda, koncis deklaration.

Nödvändiga egenskaper framtvingar att anropare anger specifika egenskaper via en objektinitierare:

public class Person
{
    public required string FirstName { get; set; }
    public required string LastName { get; set; }
}
// var missing = new Person(); // Error: required properties not set
var person = new Person { FirstName = "Grace", LastName = "Hopper" };
Console.WriteLine($"{person.FirstName} {person.LastName}"); // Grace Hopper

En djupare titt på konstruktormönster, inklusive parametervalidering och konstruktorlänkning, finns i Konstruktorer.

Statiska klasser

En static klass kan inte instansieras och innehåller endast statiska medlemmar. Använd statiska klasser för att organisera verktygsmetoder som inte fungerar på instansdata:

static class MathHelpers
{
    public static double CircleCircumference(double radius) =>
        2 * Math.PI * radius;
}
double circumference = MathHelpers.CircleCircumference(5.0);
Console.WriteLine($"Circumference: {circumference:F2}"); // Circumference: 31.42

.NET-klassbiblioteket innehåller många statiska klasser, till exempel Math och Console. En statisk klass är implicit förseglad. Du kan inte härleda från den eller instansiera den.

Objektinitierare

Med objektinitierare kan du ange egenskaper när du skapar ett objekt, utan att skriva en konstruktor för varje kombination av värden:

class ConnectionOptions
{
    public string Host { get; init; } = "localhost";
    public int Port { get; init; } = 80;
    public bool UseSsl { get; init; }
}
var options = new ConnectionOptions
{
    Host = "db.example.com",
    Port = 5432,
    UseSsl = true
};
Console.WriteLine($"{options.Host}:{options.Port} (SSL: {options.UseSsl})");
// db.example.com:5432 (SSL: True)

Objektinitierare fungerar med alla tillgängliga egenskaper som har en set eller init accessor. De kombineras naturligt med required egenskaper och med konstruktorer som accepterar vissa parametrar samtidigt som anroparen kan ange andra.

När egenskapen är en samling kan du använda en samlingsuttryck (C#-referens) för att initiera objektet.

Arv

Klasser stöder arv. Du kan definiera en ny klass som återanvänder, utökar eller ändrar beteendet för en befintlig klass. Klassen du ärver från är basklassen och den nya klassen är den härledda klassen:

var manager = new Manager("Satya", "Engineering");
Console.WriteLine($"{manager.Name} manages {manager.Department}");
// Satya manages Engineering

En klass kan ärva från en basklass och implementera flera gränssnitt. Härledda klasser ärver alla medlemmar i basklassen utom konstruktorer. Mer information finns i Arv och Gränssnitt.

Se även