Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Jótanács
Új szoftverfejlesztés? Először az Első lépések oktatóanyagokkal kezdje. Végigvezetik a programok írásán, és fokozatosan ismertetik a különböző típusokat.
Tapasztalt egy másik nyelven? Ha már ismeri a típusrendszereket, gyorsan olvassa át az érték- és a hivatkozástípusok közötti különbséget, valamint az útmutatót a típusfajta kiválasztásához, majd ugorjon az adott típusokkal kapcsolatos cikkekre.
A C# egy erősen gépelt nyelv. Minden változónak, állandónak és kifejezésnek van típusa. A fordító a típusbiztonságot úgy kényszeríti ki, hogy ellenőrzi, hogy a kód minden művelete érvényes-e az érintett típusokra. Hozzáadhat például két int értéket, de nem adhat hozzá egy int és egy 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;
Megjegyzés:
A C és a C++ nyelvtől eltérően a C# nyelvben a bool nem alakítható át int típusra.
A típusbiztonság hibákat fog fordítási időben, még a kód futtatása előtt. A fordító emellett metaadatokként ágyazza be a típusadatokat a végrehajtható fájlba, amelyeket a közös nyelvi futtatókörnyezet (CLR) a futásidőben végzett további biztonsági ellenőrzésekhez használ.
Változók deklarálása típusokkal
Amikor deklarál egy változót, explicit módon adja meg annak típusát, vagy lehetővé var teszi, hogy a fordító a hozzárendelt értékből következtetsen a típusra:
// Explicit type:
int count = 10;
double temperature = 36.6;
// Compiler-inferred type:
var name = "C#";
var items = new List<string> { "one", "two", "three" };
A metódusparamétereknek és a visszaadott értékeknek is vannak típusai. A következő metódus egy string és egy int, és visszaad egy string-t.
static string GetGreeting(string name, int visitCount)
{
return visitCount switch
{
1 => $"Welcome, {name}!",
_ => $"Welcome back, {name}! Visit #{visitCount}."
};
}
A változó deklarálása után nem módosíthatja annak típusát, és nem rendelhet hozzá olyan értéket, amely nem kompatibilis a deklarált típussal. Az értékeket más típusokra is konvertálhatja. A fordító implicit konverziókat hajt végre, amelyek nem veszítik el automatikusan az adatokat. Az explicit konverziók (castek) megkövetelik, hogy jelezze a konverziót a kódban. A további információért lásd: Kasztolás és típuskonverziók.
Beépített típusok és egyéni típusok
A C# beépített típusokat biztosít a gyakori adatokhoz: egész számokhoz, lebegőpontos számokhoz, boolés charstring. Minden C#-program további hivatkozások nélkül használhatja ezeket a beépített típusokat.
A beépített típusokon kívül több szerkezettel is létrehozhat saját típusokat:
- Osztályok – Referenciatípusok modellezési viselkedéshez és összetett objektumokhoz. Támogatja az öröklést és a polimorfizmust.
- Szerkezetek – Kis méretű, egyszerűsített adatok értéktípusai. Minden változó saját másolatot tartalmaz.
-
Rekordok – Osztályok vagy struktúrák fordító által generált egyenlőséggel
ToString, és megőrző jellegű mutáció kifejezéseken keresztülwith. - Interfészek – Szerződések, amelyek meghatározzák azokat a tagokat, amelyeket bármely osztály vagy szerkezet implementálhat.
- Számbavételek – Az integrál állandók nevesített készletei, például a hét napjai vagy a fájlhozzáférési módok.
- Tuples – Egyszerűsített szerkezeti típusok, amelyek névvel ellátott típus definiálása nélkül csoportosítják a kapcsolódó értékeket.
-
Generics – Típusparaméteres szerkezetek, például
List<T>Dictionary<TKey, TValue>típusbiztonságot biztosítanak, miközben ugyanazt a logikát használja újra a különböző típusok esetében.
Értéktípusok és referenciatípusok
A C# minden típusa értéktípus vagy referenciatípus. Ez a különbség határozza meg, hogy a változók hogyan tárolják az adatokat, és hogyan működnek a hozzárendelések.
Az értéktípusok közvetlenül tárolják az adataikat. Amikor értéktípust rendel egy új változóhoz, a futtatókörnyezet átmásolja az adatokat. Az egyik változó módosítása nincs hatással a másikra. A szerkezetek, enumerálások és a beépített numerikus típusok mind értéktípusok.
A referenciatípusok a felügyelt halom egy objektumára mutató hivatkozást tárolnak. Amikor egy referenciatípust rendel egy új változóhoz, mindkét változó ugyanarra az objektumra mutat. Az egyik változó módosításai a másikon keresztül láthatók. Az osztályok, tömbök, delegátusok és karakterláncok referenciatípusok.
Az alábbi példa a különbséget mutatja be. Az első blokk a rekordstruktúra definícióját Coords jeleníti meg, amely értéktípus. A második blokk az értéktípusok és referenciatípusok eltérő viselkedését mutatja be.
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
Minden típus végső soron a System.Object-ből származik. Az értéktípusok a System.ValueType-ból származnak, amely a object-ből származik. Ezt az egyesített hierarchiát common type system (CTS) néven nevezik. További információ az öröklésről: Öröklés.
Válassza ki, hogy milyen típusú
Amikor új típust határoz meg, a kód viselkedésének megfelelő alakzatokat választ. A kezdeti döntéshez használja az alábbi irányelveket:
- Tulajdon – Olyan értékek ideiglenes csoportosítása, amelyhez nincs szükség névvel ellátott típusra vagy viselkedésre.
-
structvagyrecord struct– Kis méretű adatok (nagyjából 64 bájt vagy annál kisebb), értékszemantika vagy megváltoztathatatlanság. A rekordstruktúra értékalapú egyenlőséget éswithkifejezéseket ad hozzá. -
record class— Elsősorban az értékalapú egyenlőségetToStringés a nem strukturált mutációt tartalmazó adatok. Támogatja az öröklést. -
class— Összetett viselkedés, polimorfizmus vagy mutable állapot. A legtöbb egyedi típus osztály. -
interface– Olyan szerződés, amelyet a nem kapcsolódó típusok megvalósíthatnak. Identitás helyett képességeket határoz meg. -
enum— Elnevezett állandók rögzített készlete, például állapotkódok vagy beállítások.
Több lehetőség is gyakran ésszerű.
Fordítási idő típusa és futásideje típusa
A változók fordítási és futási időben eltérő típusokkal rendelkezhetnek. A fordítási idő típusa a forráskód deklarált vagy kikövetkezett típusa. A futási idő típusa annak a példánynak a tényleges típusa, amelyre a változó hivatkozik. A futásidejű típusnak meg kell egyeznie a fordítási idő típusával, vagy egy olyan típusnak, amely abból származik vagy implementálja azt. A hozzárendelés csak akkor érvényes, ha implicit átalakítás létezik a futásidejű típustól a fordítási idő típusig, például identitás, hivatkozás, boxing vagy numerikus átalakítás.
// 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";
Az előző példában boxed fordítási időben a object típusú, azonban futási időben a string típusú. A hozzárendelés azért működik, mert string a következőből objectszármazik: . Hasonlóképpen, characters fordítási idejű típusú IEnumerable<char>, és a hozzárendelés működik, mert string implementálja azt az interfészt. A fordítási idő típus szabályozza a túlterhelés feloldását és a rendelkezésre álló átalakításokat. A futásidejű típus szabályozza a virtuális metódusok küldését, is kifejezéseit és switch kifejezéseit.
Lásd még
C# nyelvspecifikáció
További információkért lásd a C# nyelvi specifikációját. A nyelvi specifikáció a C#-szintaxis és -használat végleges forrása.