Kako postaviti pametne telefone i računala. Informativni portal

C # implicitna konverzija tipa. Silazne konverzije

Prijeđimo na primjere. Razred Testiranje, koji sadrži primjere, skup je podataka različitih tipova, na kojima se izvode operacije koje ilustriraju pretvorbe tipova. Ovdje je opis klase

Testiranje: korištenjem sustava;
imenski prostor TypesProject
{
javni razred Testiranje{
/// < Sažetak>
/// skup skalarnih polja različitih tipova.
///
privatni bajt b= 255;
privatni int x= 11 ;
privatni uint ux= 1111 ;
privatni float y= 5.5f;
privatni dvostruki dy= 5.55;
privatni niz s= "Zdravo!";
privatni niz si= "25";
privatni objekt obj= novi objekt ();
// Sljedeće su metode klase, dane usput
// primjeri opisa
}
}

Skup podataka klase uključuje skalarne podatke aritmetički tip varijable koje se odnose na vrijednost vrsta niza i tip objekt, koji pripadaju referentnim tipovima. Smatrajte zatvorenim (privatni) metoda ove klase je postupak WholsWho s formalnim klasnim argumentom Objekt. Procedura ispisuje na konzolu naziv argumenta koji joj je proslijeđen, njegov tip i vrijednost.

Evo njegovog teksta:

/// < Sažetak>
/// Metoda ispisuje informacije o tipu na konzolu i
/// vrijednost stvarnog argumenta. Formalno
/// argument je tipaobjekt. Pravi argument
/// može biti bilo koje vrste, od uvijek
/// implicitna konverzija u tip je dopuštenaobjekt.
///
/// Imedrugiargument
/// da priznamoargumentbilo kojitip
private void WhoIsWho (naziv niza, bilo koji objekt){
Console.WriteLine ("tip{0} je (1), vrijednost je{2}",
ime, bilo koji.GetType (), bilo.ToString ());
}

Ovdje je otvoreno (javnost) razredna metoda Testiranje, u kojem se metoda poziva više puta WholsWho s argumentima različitih vrsta:

/// < Sažetak>
/// dobiti informacije o vrsti i vrijednosti
/// proslijeđenog argumenta - varijable ili izraza
/// Sažetak>
public void WhoTest (){
WholsWho ("x", x);
WholsWho ("ux", ux);
WhoIsWho ("y", y);
WhoIsWho ("dy", dy);
WhoIsWho ("s", s);
Tko je tko ("11+ 5.55 + 5.5f", 11+ 5.55 + 5.5f);
obj= 11 + 5.55 + 5.5f;
Tko je tko(" obj", obj);
}

Imajte na umu da entitet bilo koji- formalni klasni argument Objekt, koji pri svakom pozivu dinamički mijenja tip povezujući se s objektom danim stvarnim argumentom. Stoga je tip argumenta koji se prijavljuje konzoli tip stvarnog argumenta. Također imajte na umu da je klasa naslijeđena od klase Objekt metoda Gettype vraća tip FCL, odnosno tip koji odražava tip jezika i s kojim je stvaran radovi u tijeku prilikom izvođenja 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 događa i pri obavljanju zadatka u postupku koji se razmatra.

Na sl. 11 prikazuje izlaz na konzolu kada je metoda pozvana WhoTest u navedenom postupku Glavni razreda Classi.

Slika 11. Ispis rezultata WhoTest testa

Gdje, kako i kada se izvode pretvorbe tipa?

Potreba za pretvorbom tipa javlja se u izrazima, dodjeli, zamjeni argumenata formalne metode stvarnim.

Ako, prilikom evaluacije izraza, operandi operacije imaju različite tipove, tada ih postaje potrebno baciti na isti tip. Takva se potreba javlja i kada su operandi istog tipa, ali nije u skladu s tipom operacije. Na primjer, kada se izvodi zbrajanje, operandi tipa bajt mora se baciti na tip int, budući da zbrajanje nije definirano preko bajtova. Prilikom obavljanja zadatka x= e vrsta izvora e i vrstu cilja x mora biti dosljedan. Isto tako, kada se poziva metoda, izvorni i ciljni tipovi stvarnih i formalnih argumenata također moraju biti dosljedni.

Pretvorbe referentnog tipa

Budući da operacije nad referentnim tipovima nisu definirane (iznimka su nizovi, ali se operacije nad njima, uključujući dodjelu, izvode kao nad tipovima vrijednosti), potreba za njima se javlja samo tijekom dodjele i poziva metoda.

Upišite konverzije u izraze

U C # takve se pretvorbe dijele na implicitne i eksplicitne. Implicitne pretvorbe su one pretvorbe čiji je rezultat uvijek uspješan i ne dovodi do gubitka točnosti podataka. Implicitne konverzije se izvode automatski. Za aritmetičke podatke, to znači da u implicitnim pretvorbama raspon ciljne vrste sadrži raspon originalni tip... Na primjer, pretvorba iz vrste bajt u vrsti int odnosi se na implicitno jer je raspon kao bajt je podskup raspona int. Ova konverzija je uvijek uspješna i ne može rezultirati gubitkom preciznosti.

Eksplicitne pretvorbe su legalne pretvorbe za koje nije zajamčeno da će uspjeti ili mogu dovesti do gubitka preciznosti. Takve potencijalno opasne pretvorbe programer mora izričito specificirati. Pretvorba iz vrste int u vrsti bajt odnosi se na eksplicitni jer nije siguran i može dovesti do gubitka značajnih znamenki. Imajte na umu da sve vrste nemaju eksplicitne konverzije. U ovom slučaju potrebni su drugi mehanizmi pretvorbe tipa, o čemu će biti riječi kasnije.

Pretvorbe unutar aritmetičkog tipa

Aritmetički tip, kao što je prikazano u tablici tipova podataka, dijeli se na 11 podtipova. Na sl. Slika 12 prikazuje dijagram konverzija unutar aritmetičkog tipa.

Slika 12. Hijerarhija pretvorbi unutar aritmetičkog tipa

Dijagram prikazan na slici omogućuje vam da odgovorite na niz važnih pitanja vezanih uz postojanje konverzija između vrsta. Ako dijagram prikazuje put (strelice) od tipa A do tipa B, onda to znači postojanje implicitne konverzije iz tipa A u tip B. Sve druge pretvorbe 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 inverzna u implicitna konverzija uvijek mora eksplicitno specificirati.

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

Ponekad se javlja situacija u kojoj za jednu vrstu izvora može istovremeno postojati više vrsta odredišta te je potrebno odabrati cilj – vrstu odredišta. Takvi problemi odabira nastaju, na primjer, kada se radi s preopterećenim metodama u klasama.

Pravilo za odabir implementacije pri pozivanju metode je sljedeće: odabire se implementacija za koju je put transformacije naveden u dijagramu kraći. Ako postoji točna podudarnost parametara po vrsti (put duljine 0), tada će, naravno, biti odabrana ova implementacija.

Pogledajmo još jedan testni slučaj. U razred Testiranje uključena je skupina preopterećenih metoda OLload s jednim i dva argumenta. Ove metode su:

/// < Sažetak>
/// Grupa preopterećenih metodaOLload
/// s jednim ili dva argumenta aritmetičkog tipa.
/// Ako je stvarni argument jedan, tada je jedan od
/// metode koje najviše odgovaraju tipu argumenta.
/// Prilikom pozivanja metode s dva argumenta, moguće je
/// Sukob u odabiru odgovarajuće metode, što rezultira
/// do pogreške u vremenu prevođenja.
///
privatni void OLoad (float par){
Console.WriteLine ("float value{0}", par);
}
/// < Sažetak>
/// Preopterećena metodaOLloads jednim parametrom tipadugo
///
///
privatni void OLoad (dugi par){
Console.WriteLine ("duga vrijednost (0)", par);
}
/// < Sažetak>
/// Preopterećena metodaOnLoads jednim parametrom tipaulong
///
///
privatni void OLoad (ulong par){
Console.WriteLine ("dugotrajna vrijednost (0)", par);
}
/// < Sažetak>
/// Preopterećena metodaOLloads jednim parametrom tipadvostruko
///
///
privatni void OnLoad (dvostruki par){
Console.WriteLine ("dvostruka vrijednost (0)", par);
}
/// < Sažetak>
/// Preopterećena metodaOLloads dva parametra poputdugoidugo
///
///
///
privatni void OLoad (dugi par1, dugi par2){
Console.WriteLine ("dugi par1{0}, dugi par2{1}", par1, par2);
}
/// < Sažetak>
/// Preopterećena metodaOLloads dva parametra poput
/// dvostrukoidvostruko
///
///
///
privatni void OLoad (dvostruki par1, dvostruki par2){
Console.WriteLine ("dvostruki par1{0}, dvostruki par2{1}", par1, par2);
}
/// < Sažetak>
/// Preopterećena metodaOLloads dva parametra poput
/// intiplutati
///
///
///
privatni void OLoad (int par1, float par2){
Console.WriteLine ("int par1{0}, float par2{1}", par1, par2);
}

Sve ove metode su dovoljno jednostavne. Oni pružaju informacije o vrsti i vrijednosti proslijeđenih argumenata.

Ovdje je testna procedura koja poziva metodu OLload s različitim brojem i vrstama argumenata:

/// < Sažetak>
/// Pozivanje preopterećene metodeOLload. Ovisno o
/// tip i broj argumenata poziva se jedna od grupnih metoda.
///
public void OLoadTest (){
OLopterećenje (x);
OLopterećenje (ux);
OLopterećenje (y);
OLopterećenje (dy);
// OLopterećenje (x, ux);
// sukob: (int, float)i(dugo, dugo)
OUčitavanje (x, (float) ux);
OLopterećenje (y, dy);
OLload(x, dy);
}

Imajte na umu da je jedan od poziva komentiran jer dovodi do sukoba tijekom faze prijevoda. Kako bismo eliminirali sukob prilikom pozivanja metode, morali smo specificirati eksplicitnu konverziju argumenta, koja je prikazana u retku nakon retka za komentar. Rezultat testa OLoadTest prikazan je na sl. trinaest.

Slika 13. Ispis rezultata OLoadTest-a

Eksplicitne konverzije

Kao što je ranije spomenuto, eksplicitne pretvorbe mogu biti opasne zbog gubitka preciznosti. Stoga se izvode prema uputama programera - on snosi svu odgovornost za rezultate.

Pretvorbe nizova

Važna klasa konverzija su pretvorbe u niz i obrnuto. Pretvorbe u tip niza uvijek su definirane, budući da su svi tipovi potomci osnovne klase Objekt, i, prema tome, imaju metodu ToString(). Za ugrađene tipove definirana je prikladna implementacija ove metode. Konkretno, za sve podtipove aritmetičkog tipa, metoda ToString() vraća u prikladnom obliku niz koji specificira odgovarajuću aritmetičku vrijednost. Napomena, metoda ToString može se pozvati eksplicitno, ali ako eksplicitni poziv nije naveden, tada će biti pozvan implicitno, kad god kontekst zahtijeva konverziju u vrstu niza. Evo relevantnog primjera:

/// < Sažetak>
/// Demonstracija pretvaranja podataka raznih vrsta u niz.
///
public void ToStringTest ()
{
s= " VladimirPetrov ";
s1= " Dob: ";
ux= 27;
s= s+ s1+ ux.ToString ();
s1= " Plaća: ";
dy= 2700.50;
s= s+ s1+ dy;
Tko je tko(" s", s);
}

Rezultat ovog postupka prikazan je na sl. 14.

Slika 14. Ispis rezultata ToStringTest-a

Pretvorbe iz tipa niza u druge vrste, kao što je aritmetika, moraju se izvršiti eksplicitno. Ali ne postoje eksplicitne pretvorbe između aritmetike i nizova. Potrebni su drugi mehanizmi, a dostupni su u C #. U tu svrhu možete koristiti odgovarajuće metode klase Pretvoriti FCL knjižnica ugrađena u prostor imena Sustav. Navedimo primjer:

/// < Sažetak>
/// Demonstracija pretvaranja niza u podatke raznih vrsta.
///
public void FromStringTest (){
s= " Unesidob ";
Console.WriteLine (s);
s1= Console.ReadLine ();
ux= Pretvori.ToUInt32 (s1);
Tko je tko("Dob: ",ux);
s= "Unesite plaću";
Console.WriteLine (s);
s1= Console.ReadLine ();
dy= Pretvori.ToDouble (s1);
Tko je tko ("Plaća: ", dy);
}

Ovaj primjer pokazuje unos podataka s konzole različiti tipovi... Podaci očitani s konzole po metodi ReadLine ili Čitati, uvijek predstavljaju niz, koji se zatim mora pretvoriti u željeni tip. Za to se pozivaju odgovarajuće metode klase. Pretvoriti. Naravno, da bi pretvorba uspjela, niz mora sadržavati vrijednost u formatu koji dopušta takvu konverziju. Imajte na umu, na primjer, da se prilikom pisanja vrijednosti broja za isticanje razlomka mora koristiti zarez, a ne točka; u suprotnom će se pojaviti pogreška tijekom izvođenja.

Na sl. 15 prikazuje rezultate izlaza i unosa s konzole kada se ovaj postupak izvodi.

Slika 15. Ispis rezultata FromStringTest

Implicitnu konverziju tipa podataka izvodi C++ kompajler, dok eksplicitnu konverziju tipa podataka izvodi sam programer. O pretvorbi vrste podataka reći ću sljedeće: "Rezultat bilo kojeg izračuna bit će pretvoren u najtočniju vrstu podataka od onih tipova podataka koji su uključeni u izračun." Za ilustrativni primjer Predstavit ću tablicu s konverzijama tipova podataka. Pogledajmo operaciju dijeljenja u tablici. Kao cjelobrojni tip podataka uzimamo int, pa, imat ćemo pravi tip podataka plutati.

Tablica 1 - Eksplicitna i implicitna konverzija tipa podataka u C ++
x y Rezultat divizije Primjer
dividenda šestar privatni x = 15 y = 2
int int int 15/2=7
int plutati plutati 15/2=7.5
plutati int plutati 15/2=7.5

Tablica pokazuje da promjenom varijabli na različitim mjestima rezultat ostaje isti (u našem slučaju to su djelitelj i djelitelj). Sve se radi o implicitnoj pretvorbi vrste podataka. Što se tiče eksplicitne konverzije, potrebno je izvršiti neke manipulacije, čime se mijenja rezultat izračuna. Najlakši način za eksplicitnu konverziju tipova podataka, na primjer: recimo da takve brojeve trebamo podijeliti 15 i 2, dijelimo! 15/2 = 7. Rezultat je isti kao u tablici. Ali ako napravite manje transformacije, na primjer: 15,0 / 2 = 7,5 s ovom podjelom, broj 15 je stvaran, tada će rezultat biti stvaran. Sam broj 15 nije se promijenio sa stajališta matematike, jer je 15 = 15,0. Ista tehnika bi se mogla primijeniti na dva, rezultat bi bio isti, ali bi se mogao primijeniti na dva broja odjednom, ali zašto, ako je jedan od dva dovoljan.

Drugi način eksplicitne konverzije vrsta podataka:

Float (15) / 2 // rezultat je 7,5, broj 15 se pretvara u stvarni tip podataka float. duplo (15) / 2 // rezultat je 7,5 - isto !!!

C ++ također pruža unarna operacija vrsta odljeva:

Static_cast(/ * varijabla ili broj * /)

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

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

U slučaju varijable, morate razumjeti da se u retku 2 varijabla ret ne pretvara u tip podataka float, već se stvara samo privremena kopija ret varijable s 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 #uključiti korištenje imenskog prostora std; int _tmain (int argc, _TCHAR * argv) (int int_value15 = 15, int_value2 = 2; // deklarirati dvije varijable tipa int float float_value15 = 15, float_value2 = 2; // deklarirati dvije varijable plutati 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; }

V redak 5 povezani , ova biblioteka je potrebna za korištenje raznih manipulatora, u našem slučaju - fiksna setprecision (). V redak 10posebno stvorena dva varijable poput int , na sličan način kreirane dvije varijable tipa plutati unutra redak 11, ove će varijable biti potrebne za pretvaranje njihovih vrijednosti u druge vrste podataka. Vredak 12nakon operatera cout i prebacivanje operacija na izlazni tok << postoje dva manipulatora fiksni i setprecision (). Fiksni manipulator - ovo nije parametrizirani manipulator, budući da ne prihvaća nikakve parametre, piše se bez zagrada. Ovaj manipulator se koristi zajedno s parametriziranim manipulatorom setprecision () i izvodi fiksni prikaz decimalnih mjesta. Manipulator setprecision () prikazuje broj decimalnih mjesta i ono što je naznačeno u zagradama. Vredovi 13, 14, 15, 16prikazani su primjeri implicitne konverzije tipa podataka, ovi primjeri su preuzeti izstol 1... V redovi 17, 18pokazuje jedan od načina eksplicitne transformacije podataka. Bit ove metode je da cijelom broju trebate dodati zarez i nulu. Vredovi 19, 20eksplicitna konverzija se izvodi korištenjem tipova koji se mogu pretvoriti kao funkcija, unutar čijih zagrada morate navesti vrijednost ili varijablu koju treba pretvoriti. U redcima 21, 22, 23 izvodi se eksplicitna konverzija tipa podataka korištenjem unarne operacije pretvorbe podataka. Zagrade označavaju varijablu ili vrijednost koju treba pretvoriti, a znakovi su uokvireni < > 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

V redovi 22, 23 izvodi se unarna operacija pretvorbe 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 pohranu. Dakle, od Slika 1 možete vidjeti da se na kraju nalaze simboli. Ti su znakovi dobiveni pretvaranjem brojeva u char. Brojevi su bili kodovi iz. Stoga, ako trebate prikazati bilo koji znak iz ASCII tablice, to se može učiniti kako je prikazano u redovi 22, 23, dok zamjenjuje samo traženi kod.

U programiranju se često javlja potreba za izračunima na varijablama jedne vrste, a kao rezultat dobivanje druge. Na primjer, kada dijelite cijele brojeve, dobijete real. Kada je vrijednost jedne vrste pohranjena u varijablu druge vrste, izvodi se pretvorba tipa podataka. Postoji nekoliko mehanizama za to u C #.

Implicitna konverzija vrste podataka

Implicitna konverzija se događa kada je vrijednost pohranjena u varijablu drugog tipa bez navođenja u kodu.

Da bi prevodilac C # automatski pretvorio tip podataka, moraju biti ispunjena dva uvjeta:

  • Vrsta vrijednosti i tip varijable moraju biti međusobno kompatibilni;
  • Raspon mogućih vrijednosti tipa varijable ne smije biti manji od raspona vrijednosti tipa.

Bajt a = 15; bajt b = 120; int c = a + b;

Ovaj primjer radi implicitna konverzija , a varijabla c će na kraju biti tipa int. To je moguće jer su bajt i int cijeli brojevi, a int sadrži cijeli raspon bajtova.

Još jedan primjer:

Kratki a = 815; ushort b = a; // Greška

Iako je 815 u ovom slučaju u kratkom dometu pojavit će se poruka o pogrešci... To je zbog činjenice da prevodilac za implicitnu konverziju provjerava samo gore navedene uvjete i gleda samo tipove, ne obraćajući pozornost na određene vrijednosti.

Eksplicitna konverzija vrste podataka

Ako uvjeti implicitne pretvorbe nisu ispunjeni, ali je potrebno izvršiti pretvorbu tipa, koristi se pretvorba tipa. Ovo je pokazatelj ciljane vrste u koju se rezultat izračuna treba pretvoriti, napisan u zagradama prije izraza.

Int d = 13; int c = 4; var e = (dvostruko) d / c;

Tako će varijabla e dobiti tip double i vrijednost 3,25. Ako ne bismo koristili pretvorbu, tada bi ova varijabla imala tip int i vrijednost 3 prema pravilima za dijeljenje cijelih brojeva u C #.

Još jedan primjer:

Kratki broj = 257; dvostruki dbl = 34,9318; int rnd = (kratko) dbl; // Bit će dodijeljena vrijednost 34 bajta what = (byte) num; // Bit će dodijeljena vrijednost 1

U slučaju rnd, ispunjeno je sljedeće pravilo: pri pretvaranju brojeva s pomičnim zarezom u cijele brojeve, njihov se razlomak odbacuje.

A u slučaju čega sve je malo kompliciranije. Prilikom eksplicitnog pretvaranja, prevodilac zanemaruje raspone tipova. A tijekom izvođenja programa, ako se pokuša unijeti u varijablu vrijednost koja nije u njezinom rasponu (s većom dubinom bita), tada se brišu svi bitovi visokog reda. Broj 257 u binarnom prikazu tipa ushort izgleda kao 00000001 00000001. Kada se pretvori u bajt, ostaje samo posljednji bajt 00000000, odnosno 1.

Pretvorba u kojoj raspon tipa varijable ne pokriva u potpunosti raspon tipa vrijednosti naziva se sužavanje. Kako biste izbjegli gubitak podataka, kao u prethodnom primjeru, morate koristiti provjeru prekoračenja.

Prelijevanje prilikom sužavanja konverzije podataka

Očito, ne možete zanemariti mjesta u kodu na kojima može doći do gubitka podataka zbog prelijevanja. U protivnom, varijable mogu poprimiti neočekivane vrijednosti, što će utjecati na rad programa, a uzrok greške će biti prilično teško ući u trag.

Prema zadanim postavkama, pojave prekoračenja se zanemaruju. Provjerena ključna riječ koristi se za pokretanje odgovarajuće iznimke u ovom slučaju. Može se postaviti ili ispred određenog izraza, ili s njim možete odrediti blok koda. Nadalje, kada se dogodi iznimka, može se obraditi s konstrukcijom pokušaj uhvatiti.

Random rnd = novi Random (); int veći = rnd.Sljedeće (99999); // Generira slučajni broj između 0 i 99999 short smaller; try (smaller = checked ((short) veći);) catch (System.OverflowException e) (Console.WriteLine ('Overflow podignut provjerenim na smaller:' + e.ToString ()); // Ispisuje // poruku o da je obrađena iznimka manja = -1;)

veći je slučajni broj od 0 do 99999. Ako ova vrijednost prelazi raspon kratkog tipa, bit će izbačena iznimka System.OverflowException i varijabilna manji bit će dodijeljena vrijednost -1. Ako do preljeva ne dođe, neće biti iznimke, a manja varijabla će jednostavno uzeti vrijednost veće varijable, ali u tipu kratak.

Je operater

Da biste provjerili mogućnost pretvaranja objekta u određeni tip u C #, koristite operator je... Provjerava je li objekt instanca samog tipa ili je izveden iz njega. Rezultat binarne operacije s operatorom is je booleova vrijednost (točno ili netočno).

Primjer korištenja is operatora:

Klasa Samle1 () klasa Samle2 (): Uzorak1 () // Nasljeđuje klasu Samle1 klasu Samle3 () Samle1 t1 = novi Samle1 (); Uzorak2 t2 = novi Uzorak2 (); Uzorak3 t3 = novi Uzorak3 (); char t4 = 't'; if (t1 je Sample1) (Console.WriteLine (“t1 je Sample1”);) // Bit će prikazan ako (t2 je Sample1) (Console.WriteLine (“t2 je Sample1”);) // Bit će prikazan ako ( t3 je Sample1) (Console.WriteLine (“t3 je Sample1”);) // Neće se prikazati ako (t4 je Sample1) (Console.WriteLine (“t4 je Sample1”);) // Neće se prikazati

Kao operater

Operator as koristi se za pretvaranje kompatibilnih referentnih tipova. Imajte na umu da ako pretvorba ne uspije, nema iznimke, ali se vraća null. To se mora uzeti u obzir prilikom obrade rezultata pretvorbe s as.

Class SamleClass () objekt Arr = novi objekt; Arr = novi SampleClass (); Arr = “dobrodošli”; Arr = (kratko) 654; Arr = null; za (bajt i = 0; i< Arr.Length; i++) { string t1 = Arr[i] as string; SampleClass t2 = Arr[i] as SampleClass; if (t1 != null) { Console.WriteLine(“{0}: it’s a string ‘” + t1 + “’”, i+1); } else if (t2 != null) { Console.WriteLine(“{0}: it’s a SampleClass”, i+1); } else { Console.WriteLine(“{0}: it’s not string or SampleClass”, i+1); } }

Primjer izlaza bit će sljedeći:

1: to je SampleClass

2: to je "string" dobrodošao "

3: nije string ili SampleClass

4: nije string ili SampleClass

Pretvaranje tipova pomoću klase Convert

Sistemska klasa System.Convert sadrži metode koje se mogu koristiti za pretvaranje vrijednosti osnovnih tipova podataka, kao i tipa sustava DateTime.

Pretvoriti sadrži skup metoda forme Upisati gdje je Tip zamijenjen imenom sustava ciljne vrste vrijednosti (na primjer ToChar, ToInt32, ToBoolean). Ove metode vam omogućuju izvođenje svih mogućih pretvorbi u osnovne tipove C #.

Metoda Convert.ChangeType pretvara bilo koji objekt u bilo koju određenu vrstu. Metoda izbacuje iznimku ako postoji nepodudarnost tipa ili prekoračenje.

U programiranju nije neuobičajeno da se vrijednosti varijabli jedne vrste dodijele varijablama druge vrste. Na primjer, u donjem isječku koda, cjelobrojna vrijednost kao što je int dodijeljen varijabli tipa s pomičnim zarezom plutati:
int i;plutati f;i = 10;f = i;

Ako su u jednoj operaciji zadaci pomiješani kompatibilan vrste podataka, tada se vrijednost s desne strane operatora dodjele automatski pretvara u tip naveden na lijevoj strani. Stoga, u gornjem isječku koda, vrijednost varijable i prvi put pretvoren u tip plutati a zatim dodijeljen varijabli f.

Pitanje je je li pretvorba tipa uvijek moguća? Kada će se pojaviti poruke o greškama, kako će to utjecati na pouzdanost razvijenih programa?

Zbog jakog tipkanja, nisu svi tipovi podataka u C # potpuno kompatibilni, pa stoga nisu sve pretvorbe tipova dopuštene implicitno.

Na primjer, tipovi bool i int su nekompatibilni. Istina, pretvorbu nekompatibilnih tipova još uvijek možete izvršiti donoseći. Glumi u biti znači eksplicitno ih pretvoriti.

Automatska konverzija tipa

Kada se podaci jedne vrste dodijele varijabli drugog tipa, implicitna konverzija vrste događa automatski pod sljedećim uvjetima:
1) obje vrste su kompatibilne;
2) raspon prikaza brojeva ciljnog tipa je širi od onoga izvornog tipa.
Ako su oba ova uvjeta zadovoljena, onda širi transformacija.
Na primjer, vrsta int dovoljno velik da sadrži sve važeće vrijednosti tipa bajt, a osim toga, obje vrste, int i bajt, su kompatibilni cjelobrojni tipovi, pa je implicitna konverzija za njih sasvim moguća.
Numerički tipovi, i cijeli broj i s pomičnim zarezom, prilično su međusobno kompatibilni za izvođenje pretvorbi proširenja.

Razmotrimo primjer:

korištenje sustava; imenski prostor ConsoleApplication1 (program klase (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 ();) staticintSum (int x, int y) (vraćanje x + y;)))

obrati pozornost na da metoda Sum () očekuje dva parametra int. Međutim, u metodi Main () zapravo se prosljeđuju dvije varijable tipa short. Iako se ovo može činiti kao nepodudaranje tipa, program će se kompajlirati i pokrenuti bez greške i vratiti 25 prema očekivanjima.
Razlog zašto će prevodilac ovaj kod smatrati sintaktički točnim je zato što je gubitak podataka ovdje nemoguć.
Budući da je maksimalna vrijednost (32767) koju short može zadržati unutar raspona int (čija je maksimalna vrijednost 2147483647), prevodilac će implicitno proširiti svaki kratki na int.
Formalno, izraz "proširenje" koristi se za označavanje implicitnog odbacivanja prema gore ( baciti prema gore), što ne rezultira gubitkom podataka.

Casting nekompatibilnih tipova

Iako su implicitne pretvorbe korisne, one ne uspijevaju zadovoljiti sve potrebe programiranja jer dopuštaju samo proširene pretvorbe kompatibilnih tipova. I u svim ostalim slučajevima, morate pribjeći pretvorbi tipa. Casting je naredba kompajleru za pretvaranje rezultata evaluacije izraza u navedenu vrstu. To zahtijeva eksplicitnu konverziju tipa.

Sljedeći je opći oblik uvođenja tipa:
(vrsta_cilja) izraz
Ovdje cilj_vrste označava vrstu u koju želite pretvoriti navedeni izraz.

Ako lijevanje rezultira sužavanje transformacije, tada bi se neke informacije mogle izgubiti. Na primjer, kao rezultat prevođenja s tipa long na tip int, neke informacije će se izgubiti ako je vrijednost tipa long veća od raspona prikaza brojeva za tip int, budući da se najznačajniji bitovi ove numeričke vrijednosti odbacuju .
Kada se vrijednost s pomičnim zarezom prevede na cjelobrojni tip, razlomački dio ove brojčane vrijednosti gubi se kao rezultat skraćivanja. Dakle, ako cjelobrojnoj varijabli dodijelite vrijednost 1,23, tada će kao rezultat u njoj ostati samo cijeli dio izvornog broja (1), a njegov će se razlomak (0,23) izgubiti.

Uzmimo primjer:

korištenje sustava; imenski prostor ConsoleApplication1 (classProgram (statički void Main (args niza) (int i1 = 455, i2 = 84500; decimalni dec = 7,98845m; // Cast dva int broja u kratki tip Console.WriteLine ((kratki) i1); Console. WriteLine ((short) i2); // Cast a decimal na int Console.WriteLine ((int) dec); Console.ReadLine ();)))

Rezultat ovog programa bit će:
455
18964
7

Imajte na umu da je varijabla i1 ispravno konvertirana u tip short, budući da njegova vrijednost je u rasponu ove vrste podataka. Pretvaranjem dec u int vratio se cjelobrojni dio tog broja. Pretvaranje varijable i2 vraćeno vrijednost preljeva 18964 (tj. 84500 - 2 * 32768).

Uloga System.Convert Class

Na kraju teme o pretvaranju tipova podataka, vrijedi napomenuti da u imenskom prostoru Sustav tamo je Pretvori klasu, koji se također može koristiti za proširenje i sužavanje podataka:
zbroj bajtova = Pretvori.U bajt (var1 + var2);

Jedna od prednosti pristupa koji se temelji na klasi Sustav.Pretvori je zbog činjenice da omogućuje pretvorbe između tipova podataka na jezično neutralan način.

Međutim, budući da C # ima eksplicitnu operaciju pretvorbe, korištenje klase Pretvoriti pretvaranje tipova podataka obično je stvar ukusa.

Još jedna korisna svrha metoda klase Pretvoriti sastoji se u pretvaranju string varijable u numeričku varijablu. Koristim ga dosta često! Doista, u konzolnoj aplikaciji moguć je samo unos niza, a budući da je operator Console.ReadLine () vraća niz, zatim se može dalje pretvoriti u broj pomoću odgovarajuće metode, na primjer:
int k = Pretvori.ToInt32 (Console.ReadLine ());
Ako je nemoguće pretvoriti niz u broj, dolazi do iznimke (u daljnjem tekstu iznimka - iznimka), koji se također može obraditi.

Prijeđimo na učenje C # operatora i počet ćemo s.

Tip konverzije

U programiranju nije neuobičajeno da se vrijednosti varijabli jedne vrste dodijele varijablama druge vrste. Na primjer, u sljedećem isječku koda, int je dodijeljen float:

Int i; plutati f; i = 10; f = i; // dodijeli cjelobrojnu vrijednost varijabli s plutajućim brojem

Ako su kompatibilni tipovi podataka pomiješani u jednoj operaciji dodjeljivanja, tada se vrijednost s desne strane operatora dodjele automatski pretvara u tip naznačenu na lijevoj strani. Stoga se u gornjem isječku koda vrijednost i prvo pretvara u float, a zatim se dodjeljuje f. Međutim, zbog stroge kontrole tipova, nisu svi tipovi podataka u C # potpuno kompatibilni, pa stoga nisu sve pretvorbe tipova dopuštene implicitno. Na primjer, tipovi bool i int su nekompatibilni. Istina, pretvorbu nekompatibilnih tipova još uvijek možete izvršiti donoseći... Uvođenje tipova u biti znači njihovo eksplicitno pretvaranje.

Automatska konverzija tipa

Kada se podaci jedne vrste dodijele varijabli drugog tipa, implicitna konverzija vrste se pojavljuju automatski pod sljedećim uvjetima:

  • obje vrste su kompatibilne
  • raspon prikaza brojeva ciljnog tipa širi je od onoga izvornog tipa

Ako su oba ova uvjeta zadovoljena, onda širi transformacija... Na primjer, int je dovoljno velik da zadrži sve važeće vrijednosti bajta, a osim toga, i int i byte su kompatibilni cjelobrojni tipovi, pa je implicitna konverzija za njih sasvim moguća.

Numerički tipovi, i cijeli broj i s pomičnim zarezom, prilično su međusobno kompatibilni za izvođenje pretvorbi proširenja. Razmotrimo primjer:

Korištenje sustava; koristeći System.Collections.Generic; korištenjem System.Linq; koristeći System.Text; imenski prostor ConsoleApplication1 (klasa Program (statički void Main (args niza) (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 da stignu dva parametra int. Međutim, u metodi Main () zapravo se prosljeđuju dvije varijable tipa short. Iako se ovo može činiti kao neusklađenost tipa, program će se prevesti i pokrenuti bez greške i vratiti 25 prema očekivanjima.

Razlog zašto će prevodilac ovaj kod smatrati sintaktički točnim je zato što je gubitak podataka ovdje nemoguć. Budući da je maksimalna vrijednost (32767) koju short može zadržati unutar raspona int (čija je maksimalna vrijednost 2147483647), prevodilac će implicitno proširiti svaki kratki na int. Formalno, izraz "proširenje" koristi se za označavanje implicitnog odbacivanja prema gore koje ne rezultira gubitkom podataka.

Casting nekompatibilnih tipova

Iako su implicitne pretvorbe korisne, ne udovoljavaju svim programskim potrebama jer dopuštaju samo proširene pretvorbe kompatibilnih tipova. I u svim ostalim slučajevima, morate pribjeći pretvorbi tipa. Dovođenje je naredba kompajleru za pretvaranje rezultata evaluacije izraza u navedeni tip. To zahtijeva eksplicitnu konverziju tipa. Sljedeći je opći oblik određivanja tipa:

(vrsta_cilja) izraz

Ovdje cilj_vrste označava vrstu u koju želite pretvoriti navedeni izraz.

Ako lijevanje rezultira sužavanje transformacije, tada bi se neke informacije mogle izgubiti. Na primjer, kao rezultat prevođenja s tipa long na tip int, neke informacije će se izgubiti ako je vrijednost tipa long veća od raspona prikaza brojeva za tip int, budući da se najznačajniji bitovi ove numeričke vrijednosti odbacuju . Kada se vrijednost s pomičnim zarezom prevede na cjelobrojnu vrijednost, razlomački dio ove brojčane vrijednosti gubi se kao rezultat skraćivanja. Dakle, ako cjelobrojnoj varijabli dodijelite vrijednost 1,23, tada će kao rezultat u njoj ostati samo cijeli dio izvornog broja (1), a njegov će se razlomak (0,23) izgubiti. Uzmimo primjer:

Korištenje sustava; koristeći System.Collections.Generic; korištenjem System.Linq; koristeći System.Text; imenski prostor ConsoleApplication1 (klasa Program (statički void Main (string args) (int i1 = 455, i2 = 84500; decimalni dec = 7,98845m; // Cast dva broja tipa int // da upišete short Console.WriteLine ((kratko) i1) ) ; Console.WriteLine ((kratko) i2); // Ubaci decimalni // tip u int Console.WriteLine ((int) dec); Console.ReadLine ();)))

Rezultat ovog programa bit će:

Imajte na umu da je varijabla i1 ispravno konvertirana u tip short, budući da njegova vrijednost je u rasponu ove vrste podataka. Pretvaranjem dec u int vratio se cjelobrojni dio tog broja. Pretvaranje varijable i2 vraćeno vrijednost preljeva 18964 (tj. 84500 - 2 * 32768).

Presretanje sužavajućih transformacija podataka

U prethodnom primjeru, pretvaranje varijable i2 na kratko nije prihvatljivo, budući da nastaje gubitak podataka... C # predlaže ključne riječi kao što su provjereno i neprovjereno kako bi se osiguralo da gubitak podataka ne prođe nezapaženo.

Prema zadanim postavkama, kada se ne poduzmu odgovarajuća korektivna radnja, uvjeti prelijevanja i donjeg toka javljaju se bez greške. Postoje dva načina za rukovanje uvjetima preljeva i nedostatka u vašoj aplikaciji. To se može učiniti ručno oslanjajući se na svoje znanje i vještine programiranja.

Nedostatak ovog pristupa je što čak i u slučaju maksimalnog uloženog napora, osoba i dalje ostaje osoba, a neke greške mogu izmaknuti iz očiju.

Srećom, C # pruža provjerenu ključnu riječ. Kada je izraz (ili blok izraza) zatvoren u provjerenom kontekstu, C# prevodilac generira dodatne CIL izraze kako bi provjerio uvjete prelijevanja koji mogu proizaći iz zbrajanja, množenja, oduzimanja ili dijeljenja dvaju numeričkih tipa podataka.

Ako se tijekom izvođenja dogodi uvjet prelijevanja, bit će izbačena iznimka System.OverflowException... Pogledajmo primjer u kojem ćemo poslati vrijednost iznimke na konzolu:

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

Rezultat ovog programa:

Postavite provjeru za cijeli projekt za uvjete prelijevanja

Ako gradite aplikaciju u kojoj prekoračenje nikada ne bi smjelo proći nezapaženo, mogli biste otkriti da je omatanje označenom ključnom riječi neugodno velik broj redaka koda. U takvom slučaju, kao alternativu, C# prevodilac podržava zastava / provjereno... Kada je ova zastavica aktivirana, sve aritmetičke operacije u kodu će se automatski provjeravati za moguća prekoračenja, bez korištenja checked ključne riječi za svaku od njih. Detekcija prekoračenja također dovodi do toga da se odgovarajući izuzetak izbaci tijekom izvođenja.

Da biste aktivirali ovu oznaku u Visual Studio 2010, otvorite stranicu svojstava projekta, idite na karticu Build, kliknite gumb Napredno i u dijaloškom okviru koji se otvori potvrdite okvir Provjerite ima li aritmetičkog preljeva/dolje:

Važno je napomenuti da C # pruža ključnu riječ neprovjereno, što vam omogućuje da onemogućite izbacivanje iznimke preljeva u pojedinačnim slučajevima.

Dakle, da rezimiramo upotrebu označenih i nepotvrđenih ključnih riječi u C #, imajte na umu da se prema zadanim postavkama, aritmetički prekoračenje zanemaruje u .NET runtimeu. Ako trebate obraditi pojedinačne operatore, tada treba koristiti checked ključnu riječ, a ako trebate uhvatiti sve pogreške povezane s preljevom u aplikaciji, tada morate aktivirati / 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 legalno (i stoga ne bi trebalo rezultirati iznimkom koja se baca u vrijeme izvođenja).

Vrhunski povezani članci