Kako podesiti pametne telefone i računare. Informativni portal
  • Dom
  • Greške
  • Implicitno uvođenje tipova u C#. Automatska konverzija tipa

Implicitno uvođenje tipova u C#. Automatska konverzija tipa

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

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

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

Posljednje ažuriranje: 30.07.2018

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

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

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

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

Transformacije odozdo prema gore. Upcasting

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

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

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

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

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

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

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

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

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

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

Transformacije naniže. Downcasting

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

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

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

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

Pogledajmo neke primjere transformacija:

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

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

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

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

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

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

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

Drugi primjer:

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

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

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

Metode transformacije

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

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

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

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

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

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

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

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.

Najbolji članci na ovu temu