Sdílet prostřednictvím


Systém typů jazyka C#

Návod

Začínáte s vývojem softwaru? Začněte nejprve kurzy Začínáme . Provedou vás procesem psaní programů a představují typy, jak pokračujete.

Máte zkušenosti v jiném jazyce? Pokud už rozumíte systémům typů, přehlédněte rozdíl mezi hodnotou a odkazem a průvodce pro výběr typů, poté přejděte na články o konkrétních typech.

Jazyk C# je jazyk silného typu. Každá proměnná, konstanta a výraz mají typ. Kompilátor vynucuje bezpečnost typů tím, že zkontroluje, jestli jsou všechny operace v kódu platné pro příslušné typy. Můžete například přidat dvě int hodnoty, ale nemůžete přidat int a bool.

int a = 5;
int b = a + 2; // OK

bool test = true;

// Error. Operator '+' cannot be applied to operands of type 'int' and 'bool'.
// int c = a + test;

Poznámka:

Na rozdíl od jazyka C a C++ není v jazyce C# bool převoditelný na int.

Bezpečnost typů zachytává chyby v době kompilace před spuštěním kódu. Kompilátor také vloží informace o typu do spustitelného souboru jako metadata, která modul CLR (Common Language Runtime) používá k dalším bezpečnostním kontrolám za běhu.

Deklarace proměnných s typy

Když deklarujete proměnnou, zadáte její typ explicitně nebo použijete var k tomu, aby kompilátor odvodil typ z přiřazené hodnoty:

// Explicit type:
int count = 10;
double temperature = 36.6;

// Compiler-inferred type:
var name = "C#";
var items = new List<string> { "one", "two", "three" };

Parametry metody a návratové hodnoty mají také typy. Následující metoda přebírá string a int, a vrátí string:

static string GetGreeting(string name, int visitCount)
{
    return visitCount switch
    {
        1 => $"Welcome, {name}!",
        _ => $"Welcome back, {name}! Visit #{visitCount}."
    };
}

Po deklarování proměnné nemůžete změnit jeho typ ani přiřadit hodnotu, která není kompatibilní s deklarovaným typem. Hodnoty můžete převést na jiné typy. Kompilátor provádí implicitní převody , které nepřijdou o data automaticky. Explicitní převody (přetypování) vyžadují, abyste v kódu označili převod. Další informace naleznete v tématu Přetypování a převody typů.

Předdefinované typy a vlastní typy

Jazyk C# poskytuje předdefinované typy pro běžná data: celá čísla, čísla s plovoucí desetinou čárkou, bool, chara string. Každý program jazyka C# může používat tyto předdefinované typy bez dalších odkazů.

Kromě předdefinovaných typů můžete vytvořit vlastní typy pomocí několika konstruktorů:

  • Třídy – Referenční typy pro chování modelování a komplexní objekty. Podpora dědičnosti a polymorfismu
  • Struktury – Typy hodnot pro malá, odlehčená data Každá proměnná obsahuje vlastní kopii.
  • Záznamy – třídy nebo struktury s rovností ToStringgenerovanou kompilátorem a nedestruktivní mutací prostřednictvím with výrazů.
  • Rozhraní – smlouvy, které definují členy, jež může implementovat jakákoli třída nebo struktura.
  • Výčty – pojmenované sady integrálních konstant, jako jsou dny v týdnu nebo režimy přístupu k souborům.
  • Řazené kolekce členů – zjednodušené strukturální typy, které seskupí související hodnoty bez definování pojmenovaného typu.
  • Obecné typy – typ-parametrizované konstrukty jako List<T> a Dictionary<TKey, TValue>, které poskytují bezpečnost typů při opakovaném použití stejné logiky pro různé typy.

Typy hodnot a odkazové typy

Každý typ v jazyce C# je typ hodnoty nebo typ odkazu. Tento rozdíl určuje, jak proměnné ukládají data a jak přiřazení fungují.

Typy hodnot uchovávají svá data přímo. Když přiřadíte typ hodnoty nové proměnné, modul runtime zkopíruje data. Změny jedné proměnné nemají vliv na druhou proměnnou. Struktury, výčty a předdefinované číselné typy jsou všechny typy hodnot.

Odkazové typy obsahují odkaz na objekt ve spravované haldě. Když přiřadíte typ odkazu k nové proměnné, obě proměnné odkazují na stejný objekt. Změny v jedné proměnné jsou viditelné prostřednictvím druhé. Třídy, pole, delegáty a řetězce jsou odkazové typy.

Následující příklad ukazuje rozdíl. První blok ukazuje definici struktury záznamu Coords , což je typ hodnoty. Druhý blok ukazuje odlišné chování pro typy hodnot a odkazové typy.

public readonly record struct Coords(int X, int Y);
// Value type: each variable holds its own copy
var point1 = new Coords(3, 4);
var point2 = point1;
Console.WriteLine($"point1: ({point1.X}, {point1.Y})");
Console.WriteLine($"point2: ({point2.X}, {point2.Y})");
// point1 and point2 are independent copies

// Reference type: both variables refer to the same object
var list1 = new List<int> { 1, 2, 3 };
var list2 = list1;
list2.Add(4);
Console.WriteLine($"list1 count: {list1.Count}"); // 4 — same object

Všechny typy jsou nakonec odvozeny od System.Object. Typy hodnot jsou odvozeny od System.ValueType, které jsou odvozeny z object. Tato sjednocená hierarchie se nazývá Common Type System (CTS). Další informace o dědičnosti naleznete v tématu Dědičnost.

Výběr typu

Když definujete nový typ, druh, který zvolíte, ovlivňuje, jak se chová váš kód. Pomocí následujících pokynů proveďte počáteční rozhodnutí:

  • n-tice – dočasné seskupení hodnot, které nepotřebuje pojmenovaný typ ani chování.
  • struct nebo record struct – malá data (přibližně 64 bajtů nebo méně), sémantika hodnot nebo neměnnost. Záznamové struktury přidávají rovnost založenou na hodnotách a with výrazy.
  • record class — Především data s rovností založenou na hodnotách a nedestruktivní mutací. Podporuje dědičnost.
  • class — Komplexní chování, polymorfismus nebo proměnlivý stav. Většina vlastních typů je typu tříd.
  • interface — Smlouva, kterou mohou implementovat nesouvisející typy. Definuje možnosti místo identity.
  • enum — Pevná sada pojmenovaných konstant, jako jsou stavové kódy nebo možnosti.

Více než jedna možnost je často rozumná.

Typ kompilace a typ běhu

Proměnná může mít různé typy v době kompilace a v době běhu. Typ kompilace je deklarovaný nebo odvozený typ ve zdrojovém kódu. Typ běhu je skutečný typ instance, na které proměnná odkazuje. Typ běhu musí být stejný jako typ kompilace nebo typ odvozený z něj nebo ho implementuje. Přiřazení je platné pouze v případě, že existuje implicitní převod typu za běhu na typ kompilace, jako je identita, odkaz, boxování nebo číselný převod.

// Compile-time and run-time types match:
string message = "Hello, world!";

// Compile-time type differs from run-time type:
object boxed = "This is a string at run time";
IEnumerable<char> characters = "abcdefghijklmnopqrstuvwxyz";

V předchozím příkladu má boxed při kompilaci typ object, ale za běhu typ string. Přiřazení funguje, protože string je odvozeno od object. Podobně má characters typ kompilace IEnumerable<char> a přiřazení funguje, protože string implementuje tuto rozhraní. Typ kompilace řídí rozlišení přetížení a dostupné převody. Typ běhu řídí odesílání virtuálních metod, is výrazy a switch výrazy.

Viz také

Specifikace jazyka C#

Další informace najdete ve specifikaci jazyka C#. Specifikace jazyka je konečným zdrojem syntaxe a použití jazyka C#.