Kako podesiti pametne telefone i računare. Informativni portal
  • Dom
  • Savjet
  • Casting to float c#. Type Conversion

Casting to float c#. Type Conversion

Pređimo na primjere. Klasa Testiranje, koji sadrži primjere, je skup podataka različitih tipova na kojima se izvode operacije koje ilustriraju konverzije tipova. Evo opisa klase

Testiranje: korištenjem sistema;
imenski prostor TypesProject
{
javno testiranje{
/// < sažetak>
/// skup skalarnih polja različitih tipova.
///
privatni bajt b= 255;
privatni int x= 11 ;
private uint ux= 1111 ;
privatni plovak= 5.5f;
privatni dvostruki dy= 5.55;
privatni niz s= "Zdravo!";
privatni niz si= "25";
privatni objekt obj= novi objekat();
// Sljedeće su metode klase, navedene usput
// opisi primjera
}
}

Skup podataka klase uključuje skalarne podatke aritmetički tip, vezano za tipove vrijednosti, varijable string type i tip objekt, koji pripadaju referentnim tipovima. Smatrajte zatvorenim (privatni) metoda ove klase - postupak Ko je ko sa formalnim klasnim argumentom Objekat. Procedura prikazuje konzoli ime argumenta koji joj je proslijeđen, njegov tip i vrijednost.

Evo njenog teksta:

/// < sažetak>
/// Metoda prikazuje informacije o tipu i
/// vrijednost stvarnog argumenta. Formalno
/// argument ima tipobjekt. Stvarni argument
/// može biti bilo kog tipa, jer je uvijek
/// implicitna konverzija u tip je dozvoljenaobjekt.
///
/// Imesekundaargument
/// Recimoargumentbilo kojitip
private void WhoIsWho(ime niza, bilo koji objekt){
Console.WriteLine("type{0} je (1), vrijednost je{2}",
name, any.GetType(), any.ToString());
}

Evo jednog otvorenog (javnosti) metoda klase Testiranje, u kojoj se metoda poziva više puta Ko je ko sa argumentima različitih tipova:

/// < sažetak>
/// dobiti informacije o tipu i vrijednosti
/// proslijeđen argument - varijabla ili izraz
/// sažetak>
public void WhoTest(){
WholsWho("x", x);
WholsWho("ux", ux);
WhoIsWho("y", y);
WhoIsWho("dy", dy);
WhoIsWho("s", s);
WhoIsWho("11+ 5.55 + 5.5f", 11+ 5.55 + 5.5f);
obj= 11 + 5.55 + 5.5f;
Ko je ko(" obj", obj);
}

Imajte na umu da entitet bilo koji- formalni klasni argument Objekat, koji pri svakom pozivu dinamički mijenja tip vezivanjem za objekt specificiran stvarnim argumentom. Stoga je tip argumenta ispisan na konzoli tip stvarnog argumenta. Imajte na umu i to naslijeđeno od klase Objekat metoda GetType vraća tip FCL, odnosno tip na koji se tip jezika odražava i s kojim se zapravo posao u izradi prilikom izvršavanja modula. U većini poziva, stvarni argument je varijabla - odgovarajuće svojstvo klase Testiranje, ali u jednom slučaju se prosljeđuje običan aritmetički izraz, koji se automatski pretvara u objekt. Slična situacija se dešava i prilikom obavljanja zadatka u postupku koji se razmatra.

Na sl. Slika 11 prikazuje izlaz konzole dobijen prilikom pozivanja metode WhoTest u gore navedenoj proceduri Main klasa Classi.

Slika 11. Štampanje rezultata WhoTest testa

Gdje, kako i kada se vrše konverzije tipova?

Potreba za konverzijom tipova javlja se u izrazima, dodjeli i zamjeni argumenata formalne metode stvarnim.

Ako, prilikom evaluacije izraza, operandi operacije imaju različite tipove, onda postaje neophodno da ih prevedemo na isti tip. Ova potreba se javlja i kada operandi imaju isti tip, ali nije u skladu sa tipom operacije. Na primjer, kada se vrši sabiranje, operandi tipa bajt mora biti cast za tip int, pošto sabiranje nije definirano preko bajtova. Prilikom obavljanja zadatka x= e tip izvora e i tip cilja x mora biti dogovoreno. Slično tome, kada se poziva metoda, tipovi izvora i cilja – stvarni i formalni argumenti – također moraju biti konzistentni.

Pretvorbe referentnog tipa

Pošto operacije nad referentnim tipovima nisu definisane (izuzetak su stringovi, ali se operacije nad njima, uključujući dodelu, izvode kao nad tipovima vrednosti), potreba za njima se javlja samo tokom dodeljivanja i poziva metoda.

Tip Konverzije u izrazima

U C# su takve konverzije podijeljene na implicitne i eksplicitne. Implicitne transformacije uključuju one transformacije čiji su rezultati izvršenja uvijek uspješni i ne dovode do gubitka točnosti podataka. Implicitne konverzije se izvode automatski. Za aritmetičke podatke, to znači da u implicitnim konverzijama raspon tipa odredišta sadrži raspon originalni tip. Na primjer, konverzija iz tipa bajt u tipu int se odnosi na implicitno jer je raspon tipa bajt je podskup opsega int. Ova konverzija je uvijek uspješna i ne može rezultirati gubitkom preciznosti.

Eksplicitne konverzije uključuju dozvoljene konverzije, čiji uspjeh nije zajamčen ili može dovesti do gubitka preciznosti. Takve potencijalno opasne transformacije programer mora eksplicitno specificirati. Konverzija iz tipa int u tipu bajt je eksplicitan jer nije siguran i može uzrokovati gubitak značajnih znamenki. Imajte na umu da svi tipovi nemaju eksplicitne konverzije. U ovom slučaju su potrebni drugi mehanizmi konverzije tipova, o čemu će biti riječi kasnije.

Konverzije unutar aritmetičkog tipa

Aritmetički tip, kao što je prikazano u tabeli tipova podataka, podijeljen je na 11 podtipova. Na sl. Slika 12 prikazuje dijagram transformacija unutar aritmetičkog tipa.

Slika 12. Hijerarhija konverzija unutar aritmetičkog tipa

Dijagram prikazan na slici omogućava nam da odgovorimo na niz važnih pitanja vezanih za postojanje konverzija između tipova. Ako dijagram prikazuje putanju (strelice) od tipa A do tipa B, onda to znači da postoji implicitna konverzija iz tipa A u tip B. Sve druge konverzije između podtipova aritmetičkog tipa postoje, ali su eksplicitne. Imajte na umu da u dijagramu nema ciklusa, sve su strelice jednosmjerne, tako da se konverzija natrag u implicitnu uvijek mora eksplicitno specificirati.

Put prikazan na dijagramu može biti prilično dug, ali to ne znači da se cijeli niz transformacija izvodi na ovaj put. Prisustvo puta samo ukazuje na postojanje implicitna konverzija, a sama konverzija se izvodi samo jednom, od tipa izvora A do tipa odredišta B.

Ponekad se javlja situacija u kojoj više tipova odredišta može postojati istovremeno za jedan tip izvora i potrebno je odabrati cilj - tip odredišta. Takvi problemi selekcije nastaju, na primjer, kada se radi sa preopterećenim metodama u klasama.

Pravilo za odabir implementacije prilikom pozivanja metode je sljedeće: odaberite implementaciju za koju je put transformacije specificiran u dijagramu kraći. Ako postoji tačna podudarnost parametara po tipu (puta dužine 0), tada će, naravno, biti odabrana ova konkretna implementacija.

Pogledajmo još jedan primjer testa. U razred Testiranje uključio grupu preopterećenih metoda OLoad sa jednim i dva argumenta. Ovo su metode:

/// < sažetak>
/// Grupa preopterećenih metodaOLoad
/// sa jednim ili dva argumenta aritmetičkog tipa.
/// Ako postoji samo jedan stvarni argument, tada će biti pozvan jedan od sljedećih
/// metode koje najviše odgovaraju tipu argumenta.
/// Prilikom pozivanja metode sa dva argumenta, moguće je
/// sukob u izboru odgovarajuće metode, što dovodi do
/// do greške u vremenu prevođenja.
///
privatni void OLoad (float par){
Console.WriteLine("float value{0}", par);
}
/// < sažetak>
/// Preopterećena metodaOLoadsa jednim parametrom tipadugo
///
///
privatni void OLoad (dugi par){
Console.WriteLine("duga vrijednost (0)", par);
}
/// < sažetak>
/// Preopterećena metodaOnLoadsa jednim parametrom tipaulong
///
///
privatni void OLoad (ulong par){
Console.WriteLine("ulong value (0)", par);
}
/// < sažetak>
/// Preopterećena metodaOLoadsa jednim parametrom tipaduplo
///
///
privatni void OnLoad (dvostruki par){
Console.WriteLine("dvostruka vrijednost (0)", par);
}
/// < sažetak>
/// Preopterećena metodaOLoadsa dva parametra tipadugoIdugo
///
///
///
privatni void OLload (dugi par1, dug par2){
Console.WriteLine("dugi par1{0}, dugi par2{1}", par1, par2);
}
/// < sažetak>
/// Preopterećena metodaOLoadsa dva parametra tipa
/// duploIduplo
///
///
///
privatni void OLoad (dvostruki par1, dupli par2){
Console.WriteLine("dvostruki par1{0}, dupli par2{1}", par1, par2);
}
/// < sažetak>
/// Preopterećena metodaOLoadsa dva parametra tipa
/// intIfloat
///
///
///
privatni void OLoad(int par1, float par2){
Console.WriteLine("int par1{0}, float par2{1}", par1, par2);
}

Sve ove metode su prilično jednostavne. Izvještavaju informacije o vrsti i značenju prenesenih argumenata.

Evo procedure testiranja koja poziva metodu OLoad sa različitim brojevima i vrstama argumenata:

/// < sažetak>
/// Pozivanje preopterećene metodeOLoad. U zavisnosti od
/// tip i broj argumenata se poziva jedna od grupnih metoda.
///
public void OLoadTest(){
OLload(x);
OLload(ux);
OLload(y);
OLload(dy);
// OLload(x,ux);
// sukob: (int, float)I(dugo, dugo)
OLload(x, (float) ux);
OLload(y, dy);
OLoad(x, dy);
}

Imajte na umu da je jedan od poziva komentarisan jer dovodi do sukoba u fazi emitovanja. Da bi se riješio konflikt prilikom pozivanja metode, bilo je potrebno specificirati eksplicitnu konverziju argumenata, koja je prikazana u redu nakon reda komentara. Rezultat testa OLoadTest prikazano na sl. 13.

Slika 13. Ispis rezultata OLoadTest testa

Eksplicitne konverzije

Kao što je već rečeno, eksplicitne konverzije mogu biti opasne zbog gubitka preciznosti. Stoga se izvode po nalogu programera - on snosi punu odgovornost za rezultate.

Konverzije tipa niza

Važna klasa konverzija su konverzije u tip stringa i obrnuto. Konverzije u tip stringa su uvijek definirane jer su svi tipovi potomci osnovne klase Objekat, i, prema tome, imaju metod ToString(). Za ugrađene tipove definirana je odgovarajuća implementacija ove metode. Konkretno, za sve podtipove aritmetičkog tipa, metoda ToString() vraća string u prikladnom obliku koji specificira odgovarajuću vrijednost aritmetičkog tipa. Imajte na umu da metoda ToString može se pozvati eksplicitno, ali ako eksplicitni poziv nije specificiran, on će biti pozvan implicitno kad god kontekst zahtijeva konverziju u tip stringa. Evo relevantnog primjera:

/// < sažetak>
/// Demonstracija konverzije u niz podataka različitih tipova.
///
public void ToStringTest()
{
s= " VladimirPetrov ";
s1= " Dob: ";
ux= 27;
s= s+ s1+ ux.ToString();
s1= " Plata: ";
dy= 2700.50;
s= s+ s1+ dy;
Ko je ko(" s", s);
}

Rezultat ove procedure prikazan je na sl. 14.

Slika 14. Štampanje rezultata ToStringTest testa

Konverzije iz tipa stringa u druge tipove, kao što je aritmetička, moraju se izvršiti eksplicitno. Ali ne postoje eksplicitne konverzije između aritmetike i nizova. Drugi mehanizmi su potrebni, a C# ih ima. U tu svrhu možete koristiti odgovarajuće metode klase Pretvoriti FCL biblioteka ugrađena u prostor imena Sistem. Dajemo odgovarajući primjer:

/// < sažetak>
/// Demonstracija pretvaranja niza u različite tipove podataka.
///
public void FromStringTest(){
s= " EnterDob ";
Console.WriteLine(s);
s1= Console.ReadLine();
ux= Convert.ToUInt32(s1);
Ko je ko("Dob: ",ux);
s= "Unesite platu";
Console.WriteLine(s);
s1= Console.ReadLine();
dy= Convert.ToDouble(s1);
Ko je ko("Plata: ", dy);
}

Ovaj primjer pokazuje unos konzole različite vrste. Podaci se čitaju sa konzole koristeći metodu ReadLine ili Čitaj, su uvijek string, koji zatim treba konvertirati u željeni tip. Da biste to učinili, pozovite odgovarajuće metode klase Pretvoriti. Naravno, da bi konverzija bila uspješna, niz mora sadržavati vrijednost u formatu koji dozvoljava takvu konverziju. Imajte na umu, na primjer, da kada pišete vrijednost broja, treba koristiti zarez, a ne tačka, za isticanje razlomka; u suprotnom, doći će do greške u toku izvođenja.

Na sl. Slika 15 prikazuje rezultate izlaza i unosa podataka sa konzole kada je ova procedura pokrenuta.

Slika 15. Ispis rezultata FromStringTest testa

Implicitnu konverziju tipa podataka izvodi C++ kompajler, dok eksplicitnu konverziju podataka izvodi sam programer. O konverziji tipa podataka reći ću sljedeće: „Rezultat bilo kojeg izračuna će biti konvertovan u najtačniji tip podataka iz onih tipova podataka koji su uključeni u izračunavanje.“ Za jasan primjer Predstaviću tabelu sa konverzijama tipova podataka. U tabeli ćemo razmotriti operaciju podjele. Uzmimo kao cjelobrojni tip podataka int, pa, imat ćemo pravi tip podataka float.

Tablica 1 - Eksplicitna i implicitna konverzija tipa podataka u C++
x y Rezultat podjele Primjer
dividenda razdjelnik privatni x = 15 y = 2
int int int 15/2=7
int float float 15/2=7.5
float int float 15/2=7.5

Tabela pokazuje da promjenom varijabli na različitim mjestima rezultat ostaje isti (u našem slučaju to su dividenda i djelitelj). Sve o implicitnoj konverziji tipa podataka. Što se tiče eksplicitne konverzije, ona je neophodna kako bi se izvršile neke manipulacije, čime se mijenja rezultat proračuna. Najjednostavniji način za eksplicitnu konverziju tipova podataka, na primjer: recimo da trebamo podijeliti brojeve 15 i 2, podijeliti! 15/2=7. Rezultat je isti kao u tabeli. Ali ako napravite manje transformacije, na primjer: 15,0/2=7,5 sa ovom podjelom broj 15 je realan, što znači da će rezultat biti stvaran. Sam broj 15 se nije promijenio sa matematičke tačke gledišta, jer je 15 = 15,0. Ista tehnika bi se mogla primijeniti na dva, rezultat bi bio isti, ili bi se mogla primijeniti na dva broja odjednom, ali zašto, ako je jedan od dva dovoljan.

Drugi način eksplicitne konverzije tipova podataka je:

Float(15) / 2 // rezultat je 7.5, broj 15 se pretvara u tip podataka float. double(15) / 2 // rezultat je 7,5 – ista stvar!!!

C++ takođe pruža unarnu operaciju tip cast:

Static_cast(/*promjenljiva ili broj*/)

primjer: static_cast (15)/2 rezultat je 7,5
Primjer sa varijablom:

Int ret=15; static_cast (ret)/2 //rezultat je 7,5

U slučaju varijable, morate shvatiti da se u redu 2 varijabla ret ne pretvara u tip podataka float, već se kreira samo privremena kopija ret varijable sa tipom podataka float. Razmotrimo u praksi sve metode eksplicitne i implicitne konverzije tipova podataka.

// pryeobrazovanie.cpp: Definira ulaznu točku za aplikaciju konzole. #include "stdafx.h" #include #include korištenje imenskog prostora std; int _tmain(int argc, _TCHAR* argv) ( int int_value15 = 15, int_value2 = 2; // deklarirati dvije varijable tip int float float_value15 = 15, float_value2 = 2; // proglasiti dva varijable tipa float cout<< fixed << setprecision(2) // определяем, при выводе чисел с плавающей точкой, два знака после запятой << "15 / 2 = " << int_value15 / int_value2 << endl //неявное преобразование типов данных << "15 / 2 = " << int_value15 / float_value2 << endl //неявное преобразование типов данных << "15 / 2 = " << float_value15 / int_value2 << endl //неявное преобразование типов данных << "15 / 2 = " << float_value15 / float_value2 << endl; //неявное преобразование типов данных cout << "15.0 / 2 = " << 15.0 / 2 << endl // явное преобразование типа данных, число 15.0 - число с плавающей точкой << "15 / 2.0 = " << 15 / 2.0 << endl; // явное преобразование типа данных, число 2.0 - число с плавающей точкой cout << "float(int_value15) / int_value2 = " << float(int_value15) / int_value2 << endl // явное преобразование типа данных << "15 / double(2) = " << 15 / double(2) << endl; // используя приводимый тип как функцию cout << "static_cast(15) / 2 = " << static_cast(15) / 2 << endl // унарная операция приведения типа << "static_cast(15) = " << static_cast(15) << endl // можно печатать различные символы из таблицы ASCII, << "static_cast(20) = " << static_cast(20) << endl; // в скобочках прописываем код символа, который находим в таблице ASCII system("pause"); return 0; }

IN red 5 povezan , ova biblioteka je potrebna za korištenje raznih manipulatora, u našem slučaju - fiksni setprecision() . IN red 10posebno kreirane dvije varijable tipa int , na sličan način kreirali su dvije varijable tipa plutati unutra red 11, ove varijable će biti potrebne za pretvaranje njihovih vrijednosti u druge tipove podataka. INred 12nakon operatera cout i prebacivanje operacija na izlazni tok << postoje dva manipulatora fixed i setprecision() . Manipulator popravljen - ovo nije parametrizovani manipulator, jer ne prihvata nikakve parametre i piše se bez zagrada. Ovaj manipulator se koristi zajedno sa parametriranim manipulatorom setprecision() i vrši fiksni prikaz decimalnih mjesta. Manipulator setprecision() prikazuje broj decimalnih mjesta i onaj koji je naveden u zagradama. INredovi 13, 14, 15, 16prikazani su primjeri implicitne konverzije tipa podataka, ovi primjeri su preuzeti iztabela 1. IN redovi 17, 18pokazuje jedan način eksplicitne transformacije podataka. Suština ove metode je da cijelom broju morate dodati zarez i nulu. INredovi 19, 20eksplicitna konverzija se izvodi korištenjem tipova koji se mogu pretvoriti kao funkcije, unutar čijih zagrada treba navesti vrijednost ili varijablu koju treba pretvoriti. Linije 21, 22, 23 izvode eksplicitnu konverziju tipa podataka koristeći unarnu operaciju konverzije podataka. Zagrade označavaju varijablu ili vrijednost koju treba pretvoriti, a znakove uokviriti < > tip podataka u koji se pretvara. Dolje je prikazan primjer kako program radi (vidi sliku 1).

Slika 1 - Eksplicitna i implicitna konverzija C++ tipova podataka

IN redovi 22, 23 izvodi se unarna operacija konverzije podataka, a brojevi 15 i 20 se pretvaraju u char . Ovaj tip podataka vam još nije poznat, ali zapamtite da je char tip podataka za pohranjivanje . Dakle, od slika 1 možete vidjeti da su se simboli pojavili na kraju. Ovi znakovi su dobijeni pretvaranjem brojeva u char. Brojevi su bili kodovi iz . Dakle, ako je potrebno izbaciti bilo koji znak iz ASCII tabele, to se može učiniti kao što je prikazano u redovi 22, 23, uz zamjenu samo traženog koda.

Tip Conversions

U programiranju se vrijednosti varijabli jednog tipa često pripisuju varijablama drugog tipa. Na primjer, u sljedećem isječku koda, cjelobrojna vrijednost tipa int je dodijeljena varijabli s pomičnim zarezom tipa float:

Int i; float f; i = 10; f = i; // dodjeljuje cjelobrojnu vrijednost promjenljivoj float

Ako su kompatibilni tipovi podataka pomiješani u istoj operaciji dodjeljivanja, vrijednost na desnoj strani operatora dodjeljivanja se automatski pretvara u tip specificiran na lijevoj strani. Stoga se u gornjem isječku koda vrijednost varijable i prvo pretvara u float, a zatim se dodjeljuje varijabli f. Ali zbog stroge kontrole tipova, nisu svi tipovi podataka u C# u potpunosti kompatibilni, pa stoga nisu sve konverzije tipova implicitno dozvoljene. Na primjer, tipovi bool i int su nekompatibilni. Istina, konverzija nekompatibilnih tipova se još uvijek može postići casts. Uvođenje tipova u suštini znači njihovo eksplicitno pretvaranje.

Automatska konverzija tipa

Kada se podaci jednog tipa dodijele varijabli drugog tipa, implicitna konverzija tipovi se javljaju automatski pod sljedećim uvjetima:

  • oba tipa su kompatibilna
  • raspon predstavljanja brojeva ciljnog tipa je širi od onog izvornog tipa

Ako su oba ova uslova zadovoljena, onda proširenje transformacije. Na primjer, tip int je dovoljno velik da sadrži sve važeće vrijednosti tipa byte, a osim toga, i int i byte su kompatibilni cjelobrojni tipovi i stoga je implicitna konverzija za njih sasvim moguća.

Numerički tipovi, i cjelobrojni i s pomičnim zarezom, prilično su kompatibilni jedni s drugima za izvođenje proširenja konverzija. Pogledajmo primjer:

Korišćenje sistema; koristeći System.Collections.Generic; koristeći System.Linq; koristeći System.Text; imenski prostor ConsoleApplication1 ( klasa Program ( statički void Main(string args) (kratki broj1, broj2; broj1 = 10; broj2 = 15; Console.WriteLine("(0) + (1) = (2)),num1,num2,Sum (num1,num2)); Console.ReadLine(); ) static int Sum(int x, int y) ( return x + y; ) ) )

Imajte na umu da metoda Sum() očekuje dva parametra int. Međutim, metoda Main() zapravo joj prosljeđuje dvije kratke varijable. Iako ovo može izgledati kao neusklađenost tipa, program će se kompajlirati i pokrenuti bez grešaka i vratit će 25 kako se očekuje.

Razlog zbog kojeg će kompajler ovaj kod smatrati sintaktički ispravnim je taj što ne postoji mogućnost gubitka podataka. Budući da je maksimalna vrijednost (32767) koju short može sadržavati je u rasponu od int (čija je maksimalna vrijednost 2147483647), kompajler će implicitno proširiti svaku kratku varijablu na int. Formalno, izraz "proširenje" se koristi da se odnosi na implicitno prebacivanje prema gore koje ne rezultira gubitkom podataka.

Casting nekompatibilnih tipova

Iako su implicitne konverzije tipova korisne, one ne mogu zadovoljiti sve potrebe programiranja jer dozvoljavaju samo konverzije proširenja kompatibilnih tipova. U svim ostalim slučajevima, morate pribjeći tipovima. Dovođenje- ovo je naredba kompajleru da konvertuje rezultat evaluacije izraza u navedeni tip. A ovo zahtijeva eksplicitnu konverziju tipa. Sljedeći je opći oblik lijevanja tipa:

(target_type) izraz

Evo ciljni_tip označava tip u koji je poželjno konvertovati navedeni izraz.

Ako rezultira lijevanjem tipa sužavanje transformacije, tada se neke informacije mogu izgubiti. Na primjer, prilikom prebacivanja long na int, neke informacije će se izgubiti ako je long veći od raspona int jer se bitovi visokog reda te numeričke vrijednosti odbacuju. Kada se vrijednost s pomičnim zarezom pretvori u cjelobrojnu vrijednost, razlomak ove numeričke vrijednosti se gubi kao rezultat skraćivanja. Dakle, ako dodijelite vrijednost 1,23 cjelobrojnoj varijabli, tada će kao rezultat u njoj ostati samo cijeli dio originalnog broja (1), a njegov razlomak (0,23) će biti izgubljen. Pogledajmo primjer:

Korišćenje sistema; koristeći System.Collections.Generic; koristeći System.Linq; koristeći System.Text; imenski prostor ConsoleApplication1 ( klasa Program ( static void Main(string args) ( int i1 = 455, i2 = 84500; decimalni dec = 7,98845m; // Izbacite dva broja tipa int // da otkucate short Console.WriteLine((short)i1 ) ; Console.WriteLine((short)i2); // Pretvori broj decimalnog tipa // u tip int Console.WriteLine((int)dec); Console.ReadLine(); ) ) )

Rezultat ovog programa će biti:

Imajte na umu da je varijabla i1 ispravno konvertirana u tip short, jer njegova vrijednost je unutar raspona ovog tipa podataka. Pretvaranjem dec u int vraća se cijeli broj tog broja. Vraćeno je pretvaranje varijable i2 prelivna vrijednost 18964 (tj. 84500 - 2*32768).

Presretanje sužavajućih transformacija podataka

U prethodnom primjeru, pretvaranje varijable i2 u tip short nije prihvatljivo jer nastaje gubitak podataka. Za kreiranje aplikacija u kojima se gubitak podataka ne može tolerirati, C# nudi ključne riječi kao što su provjereno I neprovjereno, koji pomažu da se osigura da gubitak podataka ne prođe nezapaženo.

Prema zadanim postavkama, kada se ne poduzmu odgovarajuća korektivna radnja, dolazi do stanja prelijevanja i nižeg protoka bez izazivanja greške. Postoje dva načina za rukovanje uslovima prelivanja i prelivanja u vašoj aplikaciji. To možete učiniti ručno, oslanjajući se na vaše znanje i vještine u programiranju.

Nedostatak ovakvog pristupa je u tome što čak i ako se uloži maksimalni napor, osoba i dalje ostaje osoba, a neke greške mogu izmaći njegovim očima.

Srećom, C# pruža označenu ključnu riječ. Kada je izraz (ili blok izraza) zatvoren u provjerenom kontekstu, C# kompajler generiše dodatne CIL instrukcije za provjeru uvjeta prelijevanja koji se mogu pojaviti kao rezultat dodavanja, množenja, oduzimanja ili dijeljenja dva numerička tipa podataka.

Ako se za vrijeme izvođenja dogodi uvjet prelijevanja, bit će izbačen izuzetak System.OverflowException. Pogledajmo primjer u kojem ćemo poslati vrijednost izuzetka na konzolu:

Korišćenje sistema; koristeći System.Collections.Generic; koristeći System.Linq; koristeći System.Text; imenski prostor ConsoleApplication1 ( klasa Program ( statički void Main (string args) ( bajt var1 = 250; bajt var2 = 150; pokušaj ( suma bajtova = provjereno((bajt)(var1+var2)); Console.WriteLine("Sum: (0 )", zbroj); ) catch (OverflowException ex) ( Console.WriteLine(ex.Message); Console.ReadLine(); ) ) ) )

Rezultat ovog programa:

Postavite provjeru za cijeli projekt za uvjete prelijevanja

Ako pravite aplikaciju u kojoj nikada ne želite da dođe do prekoračenja, možete završiti sa dosadno mnogo linija koda koje možete obaviti oko označene ključne riječi. U tom slučaju, kao alternativnu opciju, C# prevodilac podržava flag /checked. Kada je ova zastavica aktivirana, sve aritmetičke operacije u kodu će biti automatski provjerene za moguće prelivanje, bez korištenja checked ključne riječi za svaku od njih. Otkrivanje prekoračenja na sličan način uzrokuje da se odgovarajući izuzetak izbaci u vrijeme izvođenja.

Da biste aktivirali ovu zastavicu u Visual Studio 2010, potrebno je da otvorite stranicu sa svojstvima projekta, idite na karticu Build, kliknite na dugme Napredno i potvrdite okvir u dijaloškom okviru koji se otvara Provjerite ima li aritmetičkih prelivanja/podlivanja:

Važno je napomenuti da C# pruža ključnu riječ neprovjereno, što vam omogućava da onemogućite izbacivanje izuzetka prekoračenja u određenim slučajevima.

Dakle, da rezimiramo upotrebu označenih i nepotvrđenih ključnih riječi u C#, aritmetički prekoračenje se ignorira prema zadanim postavkama u .NET runtimeu. Ako trebate rukovati pojedinačnim naredbama, trebate koristiti ključnu riječ checked, a ako želite uhvatiti sve greške vezane za overflow u vašoj aplikaciji, morate omogućiti /checked zastavicu. Što se tiče neprovjerene ključne riječi, ona se može koristiti kada postoji blok koda u kojem je prekoračenje dozvoljeno (i stoga ne bi trebalo uzrokovati iznimku da se izbaci u vrijeme izvođenja).

Posljednje ažuriranje: 30.07.2018

U prethodnom poglavlju smo govorili o konverzijama objekata jednostavnih tipova. Sada se dotaknimo teme pretvaranja objekata klase. Recimo da imamo sljedeću hijerarhiju klasa:

Klasa Osoba ( javni string Ime ( get; set; ) javna Osoba (ime niza) ( Ime = ime; ) public void Display() ( Console.WriteLine($"Person (Name)"); ) ) klasa Zaposlenik: Osoba ( public string Kompanija ( get; set; ) public Employee (string name, string company) : base(name) ( Company = company; ) ) class Klijent: Osoba (javni niz Banka ( get; set; ) javni klijent (naziv niza, string banka) : baza (ime) ( Banka = banka; ) )

U ovoj hijerarhiji klasa možemo pratiti sljedeći lanac nasljeđivanja: Objekt (sve klase implicitno nasljeđuju tip Object) -> Osoba -> Employee|Client.

Štaviše, u ovoj hijerarhiji klasa, osnovni tipovi su na vrhu, a izvedeni tipovi na dnu.

Transformacije odozdo prema gore. Upcasting

Objekti izvedenog tipa (koji se nalazi na dnu hijerarhije) također predstavljaju osnovni tip. Na primjer, objekat Employee je također objekt klase Person. Što je u principu prirodno, budući da je svaki zaposlenik (Zaposleni) osoba (Osoba). A možemo napisati, na primjer, ovako:

Static void Main(string args) (Zaposleni zaposleni = novi Employee("Tom", "Microsoft"); Osoba osoba = zaposleni; // konverzija iz Employee u Person Console.WriteLine(person.Name); Console.ReadKey(); )

U ovom slučaju, varijabli person, koja predstavlja tip Person, dodjeljuje se referenca na objekat Employee. Ali da bi se referenca na objekat jedne klase pohranila u varijablu druge klase, potrebno je izvršiti konverziju tipa – u ovom slučaju iz tipa Employee u tip Person. A pošto Employee nasljeđuje klasu Person, automatski se izvodi implicitna konverzija naviše - konverzija u tip koji je na vrhu hijerarhije klasa, odnosno u osnovnu klasu.

Kao rezultat toga, varijable zaposlenih i osoba će upućivati ​​na isti objekat u memoriji, ali će varijabla person imati pristup samo dijelu koji predstavlja funkcionalnost tipa Person.

Ostale rastuće transformacije izvode se na sličan način:

Osoba osoba2 = novi klijent("Bob", "ContosoBank"); // konverzija iz klijenta u osobu

Ovdje varijabla person2, koja predstavlja tip osobe, pohranjuje referencu na objekt klijenta, tako da postoji i implicitna konverzija naviše iz klase izvedene od klijenta u osnovni tip osobe.

Implicitna konverzija naviše će se također dogoditi u sljedećem slučaju:

Objekt person1 = novi zaposleni("Tom", "Microsoft"); // od zaposlenika do objekta objekta person2 = new Client("Bob", "ContosoBank"); // od klijenta do objekta objekta person3 = new Person("Sam"); // od osobe do objekta

Pošto je tip objekta osnovni tip za sve ostale tipove, konverzija u njega će se izvršiti automatski.

Transformacije naniže. Downcasting

Ali pored konverzija naviše iz izvedenog u osnovni tip, postoje konverzije naniže ili downcasting - od osnovnog tipa do izvedenog tipa. Na primjer, u sljedećem kodu, varijabla person pohranjuje referencu na objekt Employee:

Employee employee = novi Employee("Tom", "Microsoft"); Osoba osoba = zaposleni; // konverzija iz zaposlenika u osobu

I može se postaviti pitanje da li je moguće pristupiti funkcionalnosti tipa Employee preko varijable tipa Person. Ali takve transformacije se ne dešavaju automatski, jer nije svaka osoba (objekat osoba) zaposlenik preduzeća (objekat zaposlenika). A za konverziju naniže, morate primijeniti eksplicitnu konverziju, navodeći u zagradama tip u koji želite konvertirati:

Employee employee = novi Employee("Tom", "Microsoft"); Osoba osoba = zaposleni; // konverzija iz zaposlenika u osobu //Zaposlenik zaposlenik2 = osoba; // ovo nije moguće, potrebna vam je eksplicitna konverzija Employee employee2 = (Employee)person; // konverzija iz osobe u zaposlenika

Pogledajmo neke primjere transformacija:

// Objekt Employee je također tipa object object obj = new Employee("Bill", "Microsoft"); // da pristupite mogućnostima tipa Employee, prebacite objekat na Employee tip Employee emp = (Employee) obj; // Client objekat takođe predstavlja tip Osoba Osoba person = new Client("Sam", "ContosoBank"); // konverzija iz osobe u klijenta Klijent klijent = (Klijent)osoba;

U prvom slučaju, varijabli obj se dodeljuje referenca na objekat Employee, tako da možemo konvertovati obj objekat u bilo koji tip koji se nalazi u hijerarhiji klasa između tipa objekta i tipa Employee.

Ako trebamo pristupiti nekim pojedinačnim svojstvima ili metodama objekta, onda ne moramo dodijeliti konvertirani objekt varijabli:

// Objekt Employee je također tipa object object obj = new Employee("Bill", "Microsoft"); // konverzija u tip Person za pozivanje Display metode ((Person)obj).Display(); // bilo ovako // ((Employee)obj).Display(); // pretvoriti u Employee da dobijete string svojstva kompanije comp = ((Employee)obj).Company;

U isto vrijeme, potrebno je voditi računa o takvim transformacijama. Na primjer, šta će se dogoditi u sljedećem slučaju:

// Objekt Employee je također tipa object object obj = new Employee("Bill", "Microsoft"); // konverzija u tip klijenta da se dobije string svojstva banke bank = ((Client)obj).Bank;

U ovom slučaju dobićemo grešku jer varijabla obj pohranjuje referencu na objekat Employee. Ovaj objekat je takođe objekat tipa object i Person, tako da ga možemo konvertovati u te tipove. Ali ne možemo konvertovati u tip klijenta.

Drugi primjer:

Employee emp = nova osoba("Tom"); // ! Greška Osoba osoba = nova osoba("Bob"); Zaposleni emp2 = (Zaposleni) osoba; // ! Greška

U ovom slučaju pokušavamo da konvertujemo objekat tipa Person u tip Employee, a objekat Person nije objekat Employee.

Postoji nekoliko načina da se izbjegnu ove greške konverzije.

Metode transformacije

Prvo, možete koristiti ključnu riječ as. Koristeći ga, program pokušava pretvoriti izraz u određeni tip bez izbacivanja izuzetka. Ako konverzija ne uspije, izraz će sadržavati vrijednost null:

Osoba osoba = nova osoba("Tom"); Zaposleni emp = osoba kao zaposleni; if (emp == null) ( Console.WriteLine("Konverzija nije uspjela"); ) else ( Console.WriteLine(emp.Company); )

Drugi način je uhvatiti InvalidCastException koji je izbačen kao rezultat konverzije:

Osoba osoba = nova osoba("Tom"); pokušaj ( Employee emp = (Employee)person; Console.WriteLine(emp.Company); ) catch (InvalidCastException ex) (Console.WriteLine(ex.Message); )

Treći način je da provjerite da li je konverzija važeća pomoću ključne riječi is:

Osoba osoba = nova osoba("Tom"); if(osoba je zaposlenik) (Zaposlenik emp = (Zaposlenik)osoba; Console.WriteLine(emp.Company); ) else ( Console.WriteLine("Konverzija nije dozvoljena"); )

Izraz person is Employee testira da li je varijabla person objekt tipa Employee. Ali budući da u ovom slučaju očito nije, takva provjera će vratiti false i konverzija neće raditi.

Najbolji članci na ovu temu