Kako postaviti pametne telefone i računala. Informativni portal
  • Dom
  • Pogreške
  • Implicitno uvođenje tipa u c #. Automatska konverzija tipa

Implicitno uvođenje tipa u c #. Automatska konverzija tipa

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, Dobro pravi tip podatke koje ćemo imati 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 eksplicitnog i implicitna konverzija vrste 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 dva varijable poput 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 kreirane dvije 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.

Posljednje ažuriranje: 30.07.2018

U prethodnom poglavlju govorili smo o pretvaranju objekata jednostavnih tipova. Dotaknimo se sada teme pretvaranja objekata klase. Recimo da imamo sljedeću hijerarhiju klasa:

Class Osoba (javni niz Naziv (get; set;) javna Osoba (naziv niza) (Name = ime;) public void Display () (Console.WriteLine ($ "Person (Name)");)) klasa Zaposlenik: Osoba ( javni string Tvrtka (get; set;) javni Zaposlenik (naziv niza, string tvrtka): baza (naziv) (Tvrtka = tvrtka;)) klasa Klijent: Osoba (javni niz Banka (get; set;) javni klijent (naziv niza, string banka): baza (naziv) (Bank = banka;))

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

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

Upstream transformacija. Upcasting

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

Statički void Main (args niza) (Zaposlenik zaposlenik = novi zaposlenik ("Tom", "Microsoft"); Osoba osoba = zaposlenik; // pretvoriti iz Employee u Person Console.WriteLine (person.Name); Console.ReadKey (); )

U ovom slučaju, varijabli person, koja predstavlja tip Osoba, dodjeljuje se referenca na objekt Employee. Međutim, da biste pohranili referencu na objekt jedne klase u varijablu druge klase, morate izvršiti pretvorbu tipa — u ovom slučaju, iz tipa Employee u tip Osoba. A budući da Employee nasljeđuje klasu Person, automatski se izvodi implicitna pretvorba na gore – pretvaranje u tipove koji su na vrhu hijerarhije klasa, odnosno u osnovnu klasu.

Kao rezultat toga, varijable zaposlenik i osoba pokazat će na isti objekt u memoriji, ali će varijabli person biti dostupan samo dio koji predstavlja funkcionalnost tipa Person.

Ostale uzvodne transformacije izvode se na sličan način:

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

Ovdje varijabla person2, koja predstavlja tip Osoba, drži referencu na objekt Client, tako da se implicitna konverzija odozdo prema gore također izvodi iz izvedene klase Client u osnovni tip osobe.

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

Objekt osoba1 = novi zaposlenik ("Tom", "Microsoft"); // Zaposlenik na objekt objekt person2 = novi klijent ("Bob", "ContosoBank"); // od klijenta do objekta objekt person3 = nova osoba ("Sam"); // Osoba koja prigovara

Budući da je tip objekta osnovni za sve ostale tipove, pretvorba u njega bit će izvršena automatski.

Silazne transformacije. Omalovažavanje

No, osim uzvodnih konverzija s izvedene na osnovnu vrstu, postoje downcasting ili downcasting od osnovne vrste do izvedene. Na primjer, u sljedećem kodu, varijabla person pohranjuje referencu na objekt Employee:

Zaposlenik zaposlenik = novi zaposlenik ("Tom", "Microsoft"); Osoba osoba = zaposlenik; // pretvoriti iz zaposlenika u osobu

I može se postaviti pitanje je li moguće pristupiti funkcionalnosti tipa Zaposlenik preko varijable tipa Osoba. Ali takve transformacije ne prolaze automatski, jer nije svaka osoba (objekt osoba) zaposlenik poduzeća (objekt zaposlenika). A za konverziju prema dolje, morate primijeniti eksplicitne pretvorbe, navodeći u zagradama vrstu u koju želite pretvoriti:

Zaposlenik zaposlenik = novi zaposlenik ("Tom", "Microsoft"); Osoba osoba = zaposlenik; // pretvoriti iz zaposlenika u osobu // Zaposlenik zaposlenik2 = osoba; // to nije moguće, potrebna vam je eksplicitna transformacija Zaposlenik zaposlenik2 = (Zaposlenik) osoba; // pretvoriti iz osobe u zaposlenika

Pogledajmo neke primjere transformacija:

// Objekt Employee je također tipa object object obj = new Employee ("Bill", "Microsoft"); // za pristup mogućnostima tipa Employee, cast objekt na Employee type Employee emp = (Employee) obj; // objekt Client također predstavlja tip osobe Osoba person = new Client ("Sam", "ContosoBank"); // pretvoriti iz osobe u klijenta Klijent klijent = (Klijent) osoba;

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

Ako se trebamo pozvati na neka pojedinačna svojstva ili metode objekta, onda ne moramo transformirani objekt dodijeliti varijabli:

// Objekt Employee je također tipa object object obj = new Employee ("Bill", "Microsoft"); // cast na osobu za pozivanje Display ((Person) obj) .Display (); // ili tako // ((Zaposlenik) obj) .Prikaz (); // cast na Employee da dobijete string svojstva tvrtke comp = ((Zaposlenik) obj) .Tvrtka;

Istodobno, potrebno je paziti na takve pretvorbe. Na primjer, što se događa u sljedećem slučaju:

// Objekt Employee je također tipa object object obj = new Employee ("Bill", "Microsoft"); // cast klijentu za dobivanje niza svojstva banke bank = ((Klijent) obj) .Bank;

U ovom slučaju dobit ćemo pogrešku jer varijabla obj sadrži referencu na objekt Employee. Ovaj objekt je također objekt tipova object i Person, tako da ga možemo pretvoriti u te tipove. Ali ne možemo pretvoriti u tip klijenta.

Još jedan primjer:

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

U ovom slučaju pokušavamo pretvoriti objekt tipa Osoba u tip Employee, a objekt Person nije objekt Employee.

Postoji nekoliko načina da se izbjegnu ove pogreške pretvorbe.

Metode pretvorbe

Prvo, može se koristiti ključna riječ as. Koristeći ga, program pokušava pretvoriti izraz u određeni tip bez iznimke. U slučaju neuspješne konverzije, izraz će sadržavati null vrijednost:

Osoba osoba = nova Osoba ("Tom"); Zaposlenik emp = osoba kao zaposlenik; 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 pretvorbe:

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

Treći način je testirati valjanost konverzije 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 ("Pretvorba nije dopuštena");)

Izraz person is Employee testira je li varijabla person objekt tipa Employee. Ali budući da u ovom slučaju očito nije, onda će takva provjera vratiti lažno, a pretvorba neće raditi.

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 ciljnog tipa u koji 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; dupli 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 izvršavanja 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 ciljane 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.

Vrhunski povezani članci