Luo luokkakonstruktorit ja alusta objektit
Luokan ominaisuuksien ja menetelmien lisäksi luokkamääritykset sisältävät konstruktorit, joita käytetään uusien objektien (luokkaesiintymien) alustamiseen.
Luokkakonstruktorit
Luokan konstruktori on -menetelmä, jolla on sama nimi kuin sen tyypillä (konstruktorimenetelmät käyttävät samaa nimeä kuin luokka).
Luokkakonstruktorit ovat kahdenlaisia:
- Esiintymäkonstruktorit. Esiintymäkonstruktorien avulla voidaan luoda ja alustaa esiintymäkentän muuttujia objektin luonnin yhteydessä.
- Staattiset konstruktorit. Staattisia konstruktoria käytetään staattisen tiedon alustamiseen tai tietyn toiminnon suorittamiseen, joka on suoritettava vain kerran. Staattisia konstruktoria kutsutaan automaattisesti, ennen kuin ensimmäinen esiintymä luodaan tai mihin tahansa staattiseen jäseniin viitataan.
Luokkakonstruktorit ovat oletusarvoisesti esiintymäkonstruktoria.
Esiintymän konstruktorin syntaksi
Esiintymäkonstruktori on määritetty käyttäen samaa nimeä kuin luokka, eikä se sisällä palautustyyppiä. Konstruktorin menetelmän allekirjoitus voi sisältää valinnaisen käyttöoikeuksien muokkaustoiminnon, menetelmän nimen ja sen parametriluettelon. Konstruktorin menetelmän allekirjoitukset eivät sisällä palautustyyppiä.
Seuraavassa esimerkissä näytetään yksinkertainen konstruktori luokalle, jonka nimi on Person:
public class Person
{
public Person()
{
// Field initialization and constructor logic goes here.
}
// Remaining implementation of Person class.
}
Luokilla voi olla useampi kuin yksi konstruktori. Kun luokassa on useampi kuin yksi konstruktori, konstruktorit yleensä esittävät eri argumentteja.
Seuraavassa esimerkissä näytetään luokka nimeltä Person, jossa on kaksi konstruktoria.
public class Person
{
public Person()
{
// Field initialization and constructor logic goes here.
string name = "Person One";
Console.WriteLine($"Person created: {name}");
}
public Person(string fName, string lName)
{
string name = fName + " " + lName;
Console.WriteLine($"Person created: {name}");
}
// Remaining implementation of Person class.
}
Objektien alustaminen luokkakonstruktorien avulla
Kun objekti muodostetaan käyttämällä new avainsanaa, .NET-suorituspalvelu kutsuu luokan määrityksessä liittyvää esiintymäkonstruktoria ja varaa muistia objektille.
Seuraavassa koodikatkelmassa Person-luokka määrittää yksinkertaisen esiintymäkonstruktorin.
Program-luokka sisältää Main -menetelmän, joka käyttää new-operaattoria luodakseen esiintymän Person nimeltä person1. Suorituspalvelu käynnistää Person konstruktorin heti, kun muisti on varattu uudelle objektille.
public class Person
{
public Person()
{
// Field initialization and constructor logic goes here.
}
}
static class Program
{
// the Main method is the entry point of the program.
static void Main()
{
Person person1 = new Person();
}
}
Konstruktorit, joissa on parametreja ja ilman parametreja
Jos konstruktori ei ota parametreja, sitä kutsutaan parametrittomaksi konstruktoriksi. Suorituspalvelu käynnistää parametrittoman konstruktorin, kun objekti muodostetaan käyttämällä new-operaattoria, eikä konstruktorille ole annettu argumentteja.
Muistiinpano
Ellei luokka ole staattinen, C#-kääntäjä antaa luokille ilman konstruktoria julkisen parametrittoman konstruktorin luokan esiintymän mahdollistamiseksi.
Luokat määrittävät usein konstruktorit, jotka ottavat parametreja. Parametreja ottavat konstruktorit on kutsuttava käyttämällä new-operaattoria tai peruslauseketta. Luokat voivat määrittää yhden tai useamman konstruktorin.
Seuraavassa koodikatkelmassa näkyy luokka nimeltä Person ja kolme konstruktoria:
public class Person
{
public Person()
{
// Field initialization and constructor logic goes here.
Console.WriteLine("An instance of the Person class is being instantiated without name or age parameters.");
}
public Person(string name)
{
// Field initialization and constructor logic goes here.
Console.WriteLine($"An instance of the Person class is being instantiated using a name ({name}) parameter.");
}
public Person(string name, int age)
{
// Field initialization and constructor logic goes here.
Console.WriteLine($"An instance of the Person class is being instantiated using name ({name}) and age ({age}) parameters.");
}
}
static class Program
{
// the Main method is the entry point of the program.
static void Main()
{
Person person1 = new Person();
Person person2 = new Person("Person Two");
Person person3 = new Person("Person Three", 30);
}
}
Luokat ilman konstruktoria
Jos luokalla ei ole eksplisiittisiä esiintymäkonstruktoria, C# tarjoaa parametrittoman konstruktorin, jonka avulla voit alustaa kyseisen luokan esiintymän, kuten seuraavassa esimerkissä näytetään:
public class Person
{
public int age;
public string name = "unknown";
}
class Example
{
static void Main()
{
var person = new Person();
Console.WriteLine($"Name: {person.name}, Age: {person.age}");
// Output: Name: unknown, Age: 0
}
}
Tämä konstruktori alustaa esiintymäkentät ja ominaisuudet vastaavien alustajien mukaan. Jos kentässä tai ominaisuudessa ei ole alustajaa, sen arvoksi on määritetty kentän tai ominaisuuden tyypin oletusarvo. Jos määrität vähintään yhden esiintymäkonstruktorin luokkaan, C# ei tarjoa parametritonta konstruktoria.
Alusta luokkatiedot konstruktoriparametrien avulla
Konstruktorille välitetty parametri on paikallinen konstruktorille. Parametreja käytetään usein luokan tietokenttien alustamiseen.
Seuraavassa koodikatkelmassa näkyy luokka nimeltä Person, joka alustaa personName- ja personAge-kentät:
public class Person
{
public string personName;
public string personAge;
public Person()
{
// Field initialization and constructor logic goes here.
personName = "unknown";
personAge = "unknown";
}
public Person(string name)
{
// Field initialization and constructor logic goes here.
personName = name;
personAge = "unknown";
}
public Person(string name, int age)
{
// Field initialization and constructor logic goes here.
personName = name;
personAge = age.ToString();
}
}
static class Program
{
// the Main method is the entry point of the program.
static void Main()
{
Person person1 = new Person();
Person person2 = new Person("Person Two");
Person person3 = new Person("Person Three", 30);
Console.WriteLine($"Person 1 Name: {person1.personName} Age: {person1.personAge}");
Console.WriteLine($"Person 2 Name: {person2.personName} Age: {person2.personAge}");
Console.WriteLine($"Person 3 Name: {person3.personName} Age: {person3.personAge}");
}
}
Edellisessä esimerkissä Person-luokka on määritetty kolmella konstruktorilla. Ensimmäinen konstruktori alustaa personName- ja personAge-kentät "unknown". Toinen konstruktori alustaa personName-kentän name-parametrissa välitettyun arvoon ja personAge kentän arvoon "unknown". Kolmas konstruktori alustaa personName- ja personAge-kentät name ja age parametreissa välitettyihin arvoihin.
Koska kentät ovat julkisia, niitä voi käyttää suoraan Main-menetelmällä. Kun koodi suoritetaan, luodaan seuraava tuloste:
Person 1 Name: unknown Age: unknown
Person 2 Name: Person Two Age: unknown
Person 3 Name: Person Three Age: 30
Lausekkeen leipätekstimääritykset
Jos konstruktori voidaan ottaa käyttöön yksittäisenä lausekkeena, voit käyttää lausekkeen runkomääritelmää määrittämään parametrin luokan jäseneksi, kun konstruktori otetaan käyttöön.
Esimerkiksi seuraava konstruktori alustaa modelName-kentän model-parametrille välitetty arvolla:
public class Car
{
public string modelName;
public Car(string model) => modelName = model;
}
Car luokassa on yksi julkinen kenttä, modelName, jonka tyyppi on string.
modelName-kenttään on tarkoitus tallentaa automallin nimi.
Car-luokka sisältää myös konstruktorin, joka ottaa yksittäisen merkkijonoparametrin nimeltä model. Konstruktori käyttää lausekkeen leipätekstimääritystä (jonka on merkitty => syntaksilla) modelName kentän alustamiseen model-parametrille välitetyllä arvolla. Tämä tarkoittaa sitä, että kun uusi Car objekti esiintymä luodaan, modelName kenttä asetetaan argumenttina konstruktorille annettuun arvoon.
Kuten termi lauseke ilmaisee, =>-operaattorin oikea puoli on lauseke, eikä sitä ole rajoitettu yksinkertaiseen määrityslausekkeeseen. Lauseke voi olla mikä tahansa kelvollinen C#-lauseke, joka palauttaa arvon.
Seuraava koodikatkelmä esittelee, miten voit toteuttaa lausekkeen leipätekstin määrityksen, joka suorittaa yksinkertaisen laskutoimituksen:
public class Employee
{
public int Salary;
public Employee() { }
public Employee(int annualSalary) => Salary = annualSalary;
public Employee(int weeklySalary, int numberOfWeeks) => Salary = weeklySalary * numberOfWeeks;
}
Tämä luokka voidaan luoda käyttämällä jommankumman seuraavista lausekkeista:
Employee e1 = new Employee(30000);
Employee e2 = new Employee(500, 52);
Staattiset konstruktorit
Staattisen konstruktorin avulla alustetaan staattisia tietoja tai suoritetaan tietty toiminto, joka on suoritettava vain kerran. Sitä kutsutaan automaattisesti, ennen kuin ensimmäinen esiintymä luodaan tai mihin tahansa staattiseen jäseniin viitataan. Staattista konstruktoria kutsutaan enintään kerran.
Seuraavassa koodikatkelmassa näkyy sen Person-luokan päivitetty versio, joka toteuttaa staattiset kentät ja staattisen konstruktorin:
public class Person
{
public string personName;
public string personAge;
// Static field
public static string defaultName;
public static string defaultAge;
// Static constructor
static Person()
{
// Static field initialization
defaultName = "unknown";
defaultAge = "unknown";
}
public Person()
{
// Field initialization and constructor logic goes here.
personName = defaultName;
personAge = defaultAge;
}
public Person(string name)
{
// Field initialization and constructor logic goes here.
personName = name;
personAge = defaultAge;
}
public Person(string name, int age)
{
// Field initialization and constructor logic goes here.
personName = name;
personAge = age.ToString();
}
}
Päivitetyssä Person luokassa on kaksi esiintymäkenttää, personName ja personAge, jotka kumpikin tyyppiä string. Näihin kenttiin tallennetaan henkilön nimi ja ikä.
Luokka määrittää myös kaksi staattista kenttää, defaultName ja defaultAge, myös tyyppinä string. Staattiset kentät jaetaan luokan kaikkien esiintymien kesken, ja ne alustetaan vain kerran. Tässä tapauksessa staattisia kenttiä käytetään personName- ja personAge-kenttien oletusarvojen tarjoamiseen.
Staattisen konstruktorin static Person() on vastuussa staattisten kenttien alustamisesta. Se määrittää defaultName arvoksi "unknown" ja defaultAge"unknown". Staattista konstruktoria kutsutaan automaattisesti, ennen kuin mitään luokan esiintymiä luodaan tai staattisia jäseniä käytetään.
Person-luokka sisältää kolme esiintymäkonstruktoria:
Parametriton konstruktori alustaa public Person()personName- ja personAge-kentät staattisten kenttien arvoilla defaultName ja defaultAge. Tämä tarkoittaa sitä, että jos Person-objektin luonnissa ei anneta argumentteja, sekä nimen että iän "unknown" käytetään oletusarvoja.
Konstruktorin public Person(string name) ottaa yksittäisen parametrin, name, ja alustaa personName kentän tällä arvolla.
personAge -kenttä alustetaan staattisen kentän arvolla defaultAge. Tämä konstruktori mahdollistaa Person-objektin luomisen määritetyllä nimellä oletusikää käytettäessä.
konstruktorin public Person(string name, int age) käyttää kahta parametria, name ja age. Se alustaa personName-kentän, jossa on name-parametrin arvo ja personAge-kenttä, jossa on ikäparametrin merkkijonoesitys. Tämä konstruktori mahdollistaa Person-objektin luomisen sekä määritetyllä name että age.
Staattisten konstruktorien ominaisuudet
Staattisilla konstruktorilla on seuraavat ominaisuudet:
Staattinen konstruktori ei käytä käyttöoikeuksien muokkaajia tai siinä on parametreja.
Luokalla voi olla vain yksi staattinen konstruktori.
Staattisia konstruktoria ei voida periä tai ylikuormittaa.
Staattista konstruktoria ei voi kutsua suoraan, ja se on tarkoitettu vain yleisen kielen suorituspalvelun (CLR) kutsumaksi. Se käynnistetään automaattisesti.
Käyttäjällä ei ole hallintaa siihen, milloin staattinen konstruktori suoritetaan ohjelmassa.
Staattinen konstruktori kutsutaan automaattisesti. Se alustaa luokan, ennen kuin ensimmäinen esiintymä luodaan tai kyseisessä luokassa määritettyihin staattisiin jäseniin (ei sen perusluokkiin), viitataan. Staattinen konstruktori suoritetaan ennen esiintymäkonstruktoria. Jos staattisen konstruktorin luokassa on staattisen kentän muuttujan alustajia, ne suoritetaan tekstimuotoisessa järjestyksessä, jossa ne näkyvät luokan esittelyssä. Alustajat suoritetaan välittömästi ennen staattista konstruktoria.
Jos et tarjoa staattista konstruktoria staattisen kenttien alustamiseen, kaikki staattiset kentät alustetaan oletusarvoonsa.
Jos staattinen konstruktori aiheuttaa poikkeuksen, suorituspalvelu ei käynnistä sitä toista kertaa ja tyyppi pysyy alustettuna sovellustoimialueen elinkaaren ajan. Yleensä syntyy
TypeInitializationExceptionpoikkeus, kun staattinen konstruktori ei pysty alustamaan tyyppiä tai jos staattisessa konstruktorissa esiintyy käsittelemätön poikkeus. Jos staattisia konstruktoria ei ole eksplisiittisesti määritetty lähdekoodissa, vianmääritys saattaa vaatia välikielikoodin (IL) koodin tarkastusta.Staattisen konstruktorin läsnäolo estää
BeforeFieldInit-tyypin määritteen lisäämisen. Tämä rajoittaa suorituksenaikaista optimointia.Kenttä,
static readonlyvoidaan määrittää vain osana sen esittelyä tai staattisessa konstruktorissa. Kun eksplisiittistä staattista konstruktoria ei tarvita, alusta staattiset kentät esittelyssä staattisen konstruktorin sijaan, jotta suorituksenaikainen optimointi olisi parempi.Suorituspalvelu kutsuu staattista konstruktoria enintään kerran yksittäisessä sovellustoimialueessa. Tämä kutsu tehdään lukitussa alueella tietyn luokan tyypin mukaan. Staattisen konstruktorin runkoon ei tarvita ylimääräisiä lukitusmekanismeja.
Muistiinpano
Vaikka eksplisiittinen staattinen konstruktori ei ole suoraan käytettävissä, se on dokumentoitava, mikä auttaa vianmäärityksen alustuksen poikkeuksissa.