Tutki .NET-tyyppijärjestelmää
C# on vahvasti kirjoitettu kieli. Jokaisella muuttujalla ja vakiolla on tyyppi, kuten jokaisella lausekkeella, joka antaa tulokseksi arvon. .NET-luokan kirjasto määrittää sisäiset numeeriset tyypit ja monimutkaiset tyypit, jotka edustavat monenlaisia rakenteita. Näitä rakenteita ovat tiedostojärjestelmä, verkkoyhteydet, kokoelmat ja objektien matriiseja sekä päivämäärät. Tyypillinen C#-ohjelma käyttää luokkakirjaston ja käyttäjän määrittämiä tyyppejä, jotka mallintavat ohjelman ongelmatoimialueeseen liittyviä käsitteitä.
Sisäiset tyypit
C# tarjoaa vakiojoukon sisäisiä tyyppejä. Nämä vakiotyypit edustavat kokonaislukuja, liukulukuarvoja, totuusarvolausekkeita, tekstimerkkejä, desimaaliarvoja ja muita tietotyyppejä. Käytettävissä on myös sisäisiä merkkijono- ja objektityyppejä. Voit käyttää näitä tyyppejä missä tahansa C#-ohjelmassa.
Mukautetut tyypit
Voit luoda omia mukautettuja tyyppejä struct, class, interface, enum, ja record rakenteilla. .NET-luokan kirjasto on kokoelma mukautettuja tyyppejä, joita voit käyttää omissa sovelluksissasi. Oletusarvoisesti luokan kirjaston useimmin käytetyt tyypit ovat käytettävissä missä tahansa C#-ohjelmassa. Muut tulevat saataville vain, kun lisäät projektiviittauksen niitä määrittä olevaan kokoonpanoon. Kun kääntäjällä on viittaus kokoonpanoon, voit määrittää muuttujia (ja vakioita) siinä kokoonpanossa määritettyjen tyyppien mukaan lähdekoodissa.
Yleinen tyyppijärjestelmä
On tärkeää ymmärtää kaksi peruskohtaa tyyppijärjestelmästä .NET:ssä:
Se tukee periytymisperiaatetta. Tyypit voidaan johtaa muista tyypeistä, joita kutsutaan perustyypeiksi. Johdettu tyyppi perii (joitakin rajoituksia) perustyypin menetelmät, ominaisuudet ja muut jäsenet. Perustyyppi voi puolestaan johtaa jostain muusta tyypistä, jolloin johdettu tyyppi perii molempien perustyyppien jäsenet periytymishierarkiassaan. Kaikki tyypit, mukaan lukien sisäiset numeeriset tyypit, kuten System.Int32 (C#-avainsana: int), saadaan lopulta yhdestä perustyypistä, joka on
System.Object(C#-avainsana:object). Tätä yhdistettyä tyyppihierarkiaa kutsutaan common type system (CTS) -järjestelmäksi.Jokainen CTS:n tyyppi on määritetty joko arvo- tai viitetyypiksi. Näihin tyyppeihin sisältyvät kaikki .NET-luokkakirjaston mukautetut tyypit sekä myös omat käyttäjän määrittämät tyypit. Tyypit, jotka määrität strukt-avainsanan avulla, ovat arvotyyppejä. kaikki sisäiset numeeriset tyypit ovat struktseja. Luokan tai tietueen avainsanan avulla määritetyt tyypit ovat viittaustyyppejä. Viitetyypeillä ja arvotyypeillä on erilaiset käännösaikasäännöt ja erilaiset suoritusajan toiminnot.
Seuraavasta kuvasta näet CTS:ssä arvotyyppien ja viitetyyppien välisen suhteen.
Luokat ja rakenteet ovat .NET:n yleisen tyyppijärjestelmän perusrakenteita. Ne ovat pohjimmiltaan tietorakenne, joka kiteyttää joukon tietoja ja toimintoja, jotka kuuluvat yhteen loogisena yksikkönä. Tiedot ja toiminta ovat class, struct- tai record-jäseniä. Luokan jäsenet sisältävät ominaisuuksia (tietoja), menetelmiä (toimintatapoja), kenttiä (luokan sisällä määritettyjä muuttujia) ja monia muita.
class-, struct- tai record-ilmoitus on kuin Blueprint-suunnitelma, jonka avulla luodaan esiintymiä tai objekteja suorituksen aikana. Jos määrität luokan nimeltä Person, Person on tyypin nimi. Jos määrität ja alustat muuttujan, p tyyppiä Person, p sanotaan olevan Personobjekti tai esiintymä. Voit luoda useita saman Person tyyppisiä esiintymiä, ja jokaisella esiintymällä voi olla eri arvot ominaisuuksissaan ja kentissään.
Luokka on viitetyyppi. Kun -tyyppinen objekti luodaan, muuttuja, johon objekti on määritetty, sisältää vain viittauksen kyseiseen muistiin. Kun objektiviittaus on määritetty uuteen muuttujaan, uusi muuttuja viittaa alkuperäiseen objektiin. Yhden muuttujan kautta tehdyt muutokset näkyvät toisessa muuttujassa, koska molemmat viittaavat samoihin tietoihin.
struct on arvotyyppi. Kun struct luodaan, muuttuja, johon struct määritetään, sisältää structtodelliset tiedot. Kun struct määritetään uuteen muuttujaan, tietoarvo kopioidaan. Uusi muuttuja ja alkuperäinen muuttuja sisältävät näin ollen kaksi erillistä kopiota samoista tiedoista. Yhteen kopioon tehdyt muutokset eivät vaikuta toiseen kopioon.
Tietuetyypit voivat olla viittaustyyppejä (record class) tai arvotyyppejä (record struct). Tietuetyypit sisältävät menetelmiä, jotka tukevat arvojen yhdenvertaisuutta.
Yleensä luokkia käytetään monimutkaisemman toiminnan mallintamiseen. Luokat tallentavat yleensä tiedot, jotka on tarkoitettu muokattaviksi luokkaobjektin luomisen jälkeen. Rakenteet sopivat parhaiten pienille tietorakenteille. Rakenteet tallentavat yleensä tietoja, joita ei ole tarkoitettu muokattaviksi struct luomisen jälkeen. Tietuetyypit ovat tietorakenteita, joilla on muita kääntäjän syntetisoituja jäseniä. Tietueisiin tallennetaan yleensä tietoja, joita ei ole tarkoitettu muokattaviksi objektin luomisen jälkeen.
Arvotyypit
Arvotyypit johdetaan System.ValueType, joka on johdettu System.Object. Tyypeillä, jotka johdetaan System.ValueType, on erityinen toiminta yleisen kielen suorituspalvelussa. Arvotyyppimuuttujat sisältävät suoraan niiden arvot.
struct muisti varataan sisäisesti missä tahansa kontekstissa, jossa muuttuja on määritetty. Arvotyyppisille muuttujille ei ole erillisiä kasavarauksia tai roskankeräyskustannuksia. Voit määrittää tietuerakenteiset tyypit, jotka ovat arvotyyppejä, ja sisällyttää syntetisoidut jäsenet tietueille.
Arvotyyppejä on kaksi luokkaa: struct ja enum.
Sisäiset numeeriset tyypit ovat struktseja, ja niissä on kenttiä ja menetelmiä, joita voit käyttää:
// constant field on type byte.
byte b = byte.MaxValue;
Määrität ja määrität niille arvoja aivan kuin ne eivät olisi yksinkertaisia ei-koostetyyppejä:
byte num = 0xA;
int i = 5;
char c = 'Z';
Arvotyypit on suljettu. Et voi johtaa tyyppiä mistään arvotyypistä, esimerkiksi System.Int32. Et voi määrittää struct, joka periytyisi mistä tahansa käyttäjän määrittämästä class tai struct, koska struct voi periä vain System.ValueType.
Strukt-avainsanan avulla voit luoda omia mukautettuja arvotyyppejä. Yleensä strukt-rakennetta käytetään säilönä pienille liittyville muuttujille seuraavassa esimerkissä esitetyllä tavalla:
public struct Coords
{
public int x, y;
public Coords(int p1, int p2)
{
x = p1;
y = p2;
}
}
Arvotyyppien toinen luokka on enum.
enum määrittää joukon nimettyjä kokonais vakioita. Esimerkiksi System.IO.FileMode -luettelointi .NET-luokan kirjastossa sisältää joukon nimettyjä vakioen kokonaislukuja, jotka määrittävät, miten tiedosto avataan.
enum syntaksi näkyy seuraavassa esimerkissä:
public enum FileMode
{
CreateNew = 1,
Create = 2,
Open = 3,
OpenOrCreate = 4,
Truncate = 5,
Append = 6,
}
System.IO.FileMode.Create vakion arvo on 2. Nimi on kuitenkin paljon merkityksellisempi lähdekoodia lukeville ihmisille, ja tästä syystä on parempi käyttää luettelointeja vakioliteraalilukujen sijaan.
Kaikki enums perivät kohteesta System.Enum, joka perii kohteesta System.ValueType. Myös structs koskevat kaikki säännöt: enums.
Viitetyypit
-, class-, record-, delegate-, array- ja interface -tyypit ovat .
Kun määrität viitetyyppiä olevan muuttujan, se sisältää arvon null, kunnes määrität sen tämäntyyppisen esiintymän kanssa tai luot sellaisen käyttämällä new-operaattoria.
Seuraavassa esimerkissä näytetään, miten viitetyyppimuuttujia esitellään matriiseilla:
// Declaring an array variable
int[] numbers;
// Initializing the array with a size of 5
numbers = new int[5];
// Alternatively, declaring and initializing an array in one line
int[] numbers2 = new int[] { 1, 2, 3, 4, 5 };
// Assigning a reference to another variable
int[] numbers3 = numbers2;
new-operaattori luo tyypin esiintymän ja palauttaa viittauksen kyseiseen esiintymään. Viittaus on objektin muistiosoite, ja kyseinen viite tallennetaan muuttujaan. Kun määrität viitetyyppimuuttujan toiselle muuttujalle, kopioit viittauksen, et itse objektia. Molemmat muuttujat viittaavat samaan objektiin muistissa.
Muistiinpano
Viitetyyppien lisäksi matriisit ovat kokoelmia. Kokoelmia voidaan valmistella käyttämällä kokoelmalausekkeita, jotka poistavat vaatimuksen sisällyttää new avainsana, kun matriisia ilmoitetaan ja alustetaan yhdelle riville. Esimerkki: int[] numbers = [ 1, 2, 3, 4, 5 ];.
Voit luoda luokan esiintymän käyttämällä samaa syntaksia, jota käytetään sisäänrakennettujen tyyppien alustamiseen. Seuraavassa esimerkissä näytetään, miten voit luoda luokan esiintymän:
MyClass myClass = new MyClass();
MyClass myClass2 = myClass;
new-operaattori luo luokan esiintymän ja palauttaa viittauksen kyseiseen esiintymään. Viittaus on objektin muistiosoite, ja kyseinen viite tallennetaan muuttujaan. Kun määrität viitetyyppimuuttujan toiselle muuttujalle, kopioit viittauksen, et itse objektia. Molemmat muuttujat viittaavat samaan objektiin muistissa.