Kako podesiti pametne telefone i računare. Informativni portal

C# implicitna konverzija tipa. Silazne konverzije

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 konverzija natrag u implicitnu uvijek mora biti specificirana eksplicitno.

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 putanje samo ukazuje na postojanje implicitne konverzije, 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 pri pozivanju 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; // deklarirati dvije varijable float type 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 10specijalno kreirana dva 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.

U programiranju često postoji potreba da se izvrše proračuni na varijablama jednog tipa, a kao rezultat se dobije drugi. Na primjer, kada dijelite cijele brojeve, dobijete realan broj. Kada je vrijednost jednog tipa pohranjena u varijablu drugog tipa, vrši se konverzija tipa podataka. U C# ovo se implementira pomoću nekoliko mehanizama.

Implicitna konverzija tipa podataka

Do implicitne konverzije dolazi kada je vrijednost pohranjena u varijablu drugog tipa, a da nije navedena u kodu.

Da bi C# kompajler automatski konvertovao tip podataka, dva uslova moraju biti tačna:

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

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

U ovom primjeru radimo implicitna konverzija , a varijabla c će na kraju biti tipa int. Ovo je moguće jer su bajt i int vrijednosti cjelobrojne, a tip int u potpunosti uključuje raspon bajtova.

Još jedan primjer:

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

Iako je broj 815 u ovom slučaju u kratkom dometu pojavit će se poruka o grešci. To je zbog činjenice da kompajler za implicitnu konverziju provjerava samo gore navedene uslove i gleda samo tipove, ne obraćajući pažnju na specifične vrijednosti.

Eksplicitna konverzija tipa podataka

Ako uvjeti za implicitnu konverziju nisu ispunjeni, ali se mora izvršiti konverzija tipa, koristi se prebacivanje tipa. Ovo je indikacija ciljanog tipa u koji treba konvertovati rezultat izračunavanja, napisan u zagradama prije izraza.

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

Tako će varijabla e imati tip double i vrijednost 3.25. Da nismo koristili konverziju, ova varijabla bi imala tip int i vrijednost 3 prema pravilima za podjelu cijelih brojeva u C#.

Drugi primjer:

Kratki broj = 257; dupli dbl = 34,9318; int rnd = (kratko) dbl; // Biće dodeljena vrednost 34 bajta what = (byte) num; // Biće dodeljena vrednost 1

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

A u slučaju čega sve je malo komplikovanije. Prilikom izvođenja eksplicitne konverzije, kompajler ne obraća pažnju na opsege tipova. A tokom izvršavanja programa, ako se pokuša unijeti vrijednost u varijablu koja nije u njenom opsegu (sa većom dubinom bita), tada se brišu svi bitovi visokog reda. Broj 257 u kratkom binarnom prikazu izgleda kao 00000001 00000001. Kada se pretvori u bajt, ostaje samo posljednji bajt 00000000, odnosno 1.

Konverzija u kojoj raspon tipa varijable ne pokriva u potpunosti raspon tipa vrijednosti naziva se konverzija sužavanja. Da biste izbjegli gubitak podataka, kao u prethodnom primjeru, trebate koristiti provjeru prelijevanja.

Sužavanje prelivanja konverzije podataka

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

Po defaultu, pojava prekoračenja se zanemaruje. Da bi se osiguralo da se u ovom slučaju podigne odgovarajući izuzetak, koristi se provjerena ključna riječ. Može se postaviti ili ispred određenog izraza ili da se njime označi blok koda. Zatim, kada se dogodi izuzetak, njime se može rukovati pomoću konstrukcije probaj i uhvati.

Random rnd = novi Random(); int veći = rnd.Sljedeći(99999); // Generira slučajni broj od 0 do 99999 short smaller; try ( smaller = checked((short) bigger); ) catch (System.OverflowException e) ( Console.WriteLine('Overflow podignut od checked on smaller: ' + e.ToString()); // Ispisuje //poruku o da je izuzetak obrađen manji = -1;)

veći je slučajni broj od 0 do 99999. Ako ova vrijednost premašuje raspon kratkog tipa, bit će izbačen izuzetak System.OverflowException i varijabilna manjiće biti dodijeljena vrijednost -1. Ako ne dođe do prelivanja, neće biti izuzetka, a manja varijabla će jednostavno uzeti vrijednost veće varijable, ali u tipu kratko.

je operater

Da bi se provjerilo da li se objekt može prebaciti na određeni tip u C#, koristi se operator je. Provjerava da li je objekt instanca samog specificiranog tipa ili njegov derivat. Rezultat binarne operacije sa is operatorom je Boolean vrijednost (tačno ili netačno).

Primjer korištenja is operatora:

Class Samle1 () class Samle2 () : Samle1 () // Nasljeđuje klasu Samle1 class Samle3 () Samle1 t1 = new Samle1(); Uzorak2 t2 = novi Uzorak2(); Uzorak3 t3 = novi Uzorak3(); char t4 = 't'; if (t1 je Uzorak1) ( Console.WriteLine(“t1 je Uzorak1”); ) // Biće ispisan ako (t2 je Uzorak1) ( Console.WriteLine(“t2 je Uzorak1”); ) // Biće ispisan ako ( t3 je Uzorak1) ( Console.WriteLine(“t3 je Uzorak1”); ) // Neće se ispisati ako (t4 je Uzorak1) ( Console.WriteLine(“t4 je Uzorak1”); ) // Neće se ispisati

Operater kao

Operator as se koristi za pretvaranje kompatibilnih referentnih tipova. Treba napomenuti da ako konverzija nije moguća, izuzetak se ne izbacuje, već se vraća null. Ovo se mora uzeti u obzir prilikom obrade rezultata konverzije koristeći as.

Class SamleClass() object Arr = novi objekat; 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); } }

Izlaz primjera bi bio sljedeći:

1: to je SampleClass

2: to je niz "dobrodošli"

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 sistema DateTime.

Pretvoriti sadrži skup metoda kao što su Kucati, gdje je Tip zamijenjen imenom sistema ciljnog tipa vrijednosti (na primjer ToChar, ToInt32, ToBoolean). Ove metode vam omogućavaju da izvršite sve moguće konverzije iz osnovnih C# tipova.

Metoda Convert.ChangeType pretvara bilo koji objekat u bilo koji specificirani tip. Ako postoji neslaganje tipa ili prelivanje, metoda izbacuje izuzetak.

U programiranju se vrijednosti varijabli jednog tipa često pripisuju varijablama drugog tipa. Na primjer, u isječku koda ispod, cjelobrojna vrijednost tipa int dodijeljen varijabli s pomičnim zarezom float:
int i;float f;i = 10;f = i;

Ako su zadaci pomiješani u jednoj operaciji kompatibilan tipovima podataka, vrijednost na desnoj strani operatora dodjeljivanja se automatski pretvara u tip specificiran na lijevoj strani. Dakle, u gornjem isječku koda vrijednost varijable je i prvo pretvoren u tip float a zatim dodijeljen varijabli f.

Zapitajmo se: da li je konverzija tipova uvijek moguća? Kada se pojave poruke o grešci, kako će to uticati na pouzdanost programa koji se razvijaju?

Zbog stroge provjere 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. Cast, u suštini znači njihovu eksplicitnu transformaciju.

Automatska konverzija tipa

Kada se podaci jednog tipa dodijele varijabli drugog tipa, implicitna konverzija vrste koje se dešavaju automatski pod sljedećim uslovima:
1) oba tipa su kompatibilna;
2) opseg reprezentacije brojeva ciljnog tipa je širi od onog izvornog tipa.
Ako su oba ova uslova zadovoljena, onda proširenje transformacije.
Na primjer, upišite int dovoljno velika da sadrži sve važeće vrijednosti tipa bajt i pored toga, oba tipa, int I bajt, su kompatibilni integralni tipovi, pa 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štenje sistema; imenski prostor ConsoleApplication1 ( classProgram ( 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; ) ) )

obratite pažnju na da metoda Sum() očekuje da stignu dva parametra tipa 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 zašto će kompajler smatrati ovaj kod 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 bacanje prema gore ( upward cast), što ne dovodi do gubitka 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. Prebacivanje je naredba kompajleru da konvertuje rezultat izraza u specificirani tip. A ovo zahtijeva eksplicitnu konverziju tipa.

Sljedeći je opći oblik lijevanja tipa:
(target_type) izraz
Evo target_type 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 cjelobrojni tip, razlomački dio 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štenje sistema; imenski prostor ConsoleApplication1 ( classProgram ( static void Main(string args) ( int i1 =455,i2 =84500; decimal dec =7,98845m; // Pretvori dva int broja u tip 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:
455
18964
7

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).

Uloga klase System.Convert

Da zaključimo temu konverzije tipova podataka, vrijedi napomenuti da u imenskom prostoru Sistem dostupan Pretvori klasu, koji se također može koristiti za proširenje i sužavanje podataka:
zbroj bajtova = Convert.ToByte(var1 + var2);

Jedna od prednosti razrednog pristupa System.Convert To je zbog činjenice da omogućava da se konverzije između tipova podataka izvode na jezički neutralan način.

Međutim, pošto C# ima eksplicitnu operaciju konverzije, koristeći klasu Pretvoriti Konvertovanje tipova podataka je obično stvar ukusa.

Druge korisne svrhe klasa metoda Pretvoriti sastoji se od pretvaranja string varijable u varijablu numeričkog tipa. Koristim ga dosta često! Na kraju krajeva, u konzolnoj aplikaciji moguć je samo unos stringova, i to od operatora Console.ReadLine() vraća string, onda se može pretvoriti u broj koristeći odgovarajuću metodu, na primjer:
int k = Convert.ToInt32(Console.ReadLine());
Ako je nemoguće pretvoriti niz u broj, dolazi do izuzetka (u daljem tekstu: izuzetak: izuzetak), koji se takođe može obraditi.

Pređimo na proučavanje operatora jezika C# i počećemo sa .

Tip Konverzije

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 ( static 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 zašto će kompajler smatrati ovaj kod 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 target_type 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 da se izbaci izuzetak u vrijeme izvođenja).

Najbolji članci na ovu temu