Types, objecten, Stack & Heap, C# Presentatie PDF

Summary

This Odisee presentation covers C# Programming topics like types, objects, stacks, and heaps, with examples emphasizing reference and value types, boxing, unboxing, and overflow scenarios.

Full Transcript

Types Werken met types binnen de CLR Sam Van Buggenhout 2 INHOUDSTAFEL Inleiding Casting Types, objecten, stack en heap Primitieve types Reference & Value Types Dyn...

Types Werken met types binnen de CLR Sam Van Buggenhout 2 INHOUDSTAFEL Inleiding Casting Types, objecten, stack en heap Primitieve types Reference & Value Types Dynamic 3 Inleiding 4 System.Object De runtime vereist dat alle types overerven van  System.Object public class Persoon { public class Persoon : System.Object { //... //... } } Impliciete overerving Expliciete overerving 5 System.Object Omwille van overering  elk type erft aantal methodes over  Methode Public/ Beschrijving Protected Equals Public Returnt true indien twee objecten dezelfde waarde hebben GetHashCode Public Returnt de hash-code van een object. Types die gebruikt worden als key in een dictionary, moeten deze methode overriden. ToString Public Returnt default de volledige naam van het type. Kan best overschreven worden om “state” van object weer te geven. GetType Public Returnt een instantie van het type, afgeleid van de base- klasse Type, die het type van het object aangeeft. MemberwiseClone Protected Creëert een nieuwe instantie van het type en stelt de instance-fields van dit object in op de waarden van het this- object. De reference naar dit nieuwe object wordt gereturned. Finalize Protected Wordt aangeroepen door de garbage collector, wanneer deze bepaalt dat dit object moet opgeruimd worden. 6 Overriden indien “opkuis”-logica nodig. new-operator  CLR vereist dat object gemaakt wordt met new-operator  new 1. Bepaalt de benodigde grootte:  Som van de grootte van elk field  Inclusief grootte van basetype fields  Grootte van vaste gegevens  Type object pointer  Sync block index 7 new-operator  new 2. Reserveert geheugen voor het type  Zet alle bytes van het type = 0 3. Initialiseert  Type object pointer  Sync block index members 4. Constructor wordt opgeroepen  Base class constructor wordt opgeroepen  …  Constructor van System.Object wordt opgeroepen en uitgevoerd  …  Constructor wordt uitgevoerd  Constructor wordt uitgevoerd 8 new-operator  Resultaat new-operator: reference (pointer) naar nieuw object  Er is geen complementaire delete-operator  Geheugen wordt vrijgegeven door CLR  Taak van Garbage Collector om objecten “op te ruimen” 9 Casting 10 Casting Type-safety is belangrijke feature van CLR   GetType() is niet virtual  kan niet overschreven worden  security! CLR laat altijd toe:  Student student = new Student(); //zelfde type Person person = new Student(); //naar base-type object obj = person; //naar base-type 11 Casting Casting:   Via (nieuw type)waarde óf as-operator  as-operator returnt null indien cast niet mogelijk is Person p = new Student(); Student s = (Student)p; //naar afgeleid-type Student s2 = p as Student; //via as-operator object cat = new Cat(); Person p2 = cat as Person; //geen cast mogelijk -> p2 = null Cat cat2 = new Cat(); Person p3 = cat2 as Person; //compilatie-fout 12 Casting - Oefening Beschouw onderstaande situatie:  class B { } //Base class class D : B { } //Derived class Vul de tabel verder aan:   OK = toegelaten  CTE = compile-time error  RTE = runtime-error 13 Casting – Oefening (oplossing) 14 Namespaces  Logische groepering van gerelateerde types  CLR werkt steeds volledige naam  Kent concept van “namespaces” niet Opgelet voor ambiguïteit!  Math.MyMethod(); //MyNamespace.Math System.Math.Sqrt(16); //System.Math using ExternalMath = System.Math; Math.MyMethod(); ExternalMath.Sqrt(16); //gebruik alias 15 Types, objecten, stack en heap 16 Types, objecten, stack en heap Stack:   LIFO (last in, first out)  Push: plaatst waarde “bovenop” de stack  Pop: haalt waarde van bovenaan de stack  Lokale variabelen binnen methode worden op stack gepusht  Lokale variabelen die tot eenzelfde methode behoren, worden gegroepeerd in “stack frame”  Als methode eindigt: stackframe van methode wordt van stack gepopt  variabelen van methode gaan “out-of-scope”  stackframe van vorige methode opnieuw bovenaan de stack Ontwerpen van types 17 Types, objecten, stack en heap Heap:   geheugenruimte  “managed heap” (beheerd door CLR)  Objecten bewaren die langer moeten bewaard blijven dan in methode  Wordt bewaard om reference-types in op te slaan  Garbage collector beheert objecten op de heap Ontwerpen van types 18 Types, objecten, stack en heap Ontwerpen van types 19 Types, objecten, stack en heap Ontwerpen van types 20 Types, objecten, stack en heap Ontwerpen van types 21 Types, objecten, stack en heap Ontwerpen van types 22 Types, objecten, stack en heap Ontwerpen van types 23 Types, objecten, stack en heap Ontwerpen van types 24 Types, objecten, stack en heap Ontwerpen van types 25 Types, objecten, stack en heap Een complexer voorbeeld 26 Reference types in runtime Uitgangspunt:  27 Reference types in runtime Types 28 Reference types in runtime Ontwerpen van types 29 Reference types in runtime Ontwerpen van types 30 Reference types in runtime JIT Ontwerpen van types 31 Reference types in runtime JIT Ontwerpen van types 32 Reference types in runtime JIT Ontwerpen van types 33 Reference types in runtime Ontwerpen van types 34 Primitieve types 35 Primitive types – FCL  Primitive types = types die onmiddellijk door de compiler worden ondersteund  Primitive types worden vertaald naar FCL types System.Int32 a = new System.Int32(); int b = new int(); System.Int32 c = 0; int d = 0; 36 Primitive types – FCL C# primitives FCL Type CLS compliant (System.) sbyte Sbyte Nee byte Byte Ja short Int16 Ja ushort UInt16 Nee int Int32 Ja uint UInt32 Nee long Int64 Ja ulong UInt64 Nee char Char Ja float Single Ja double Double Ja bool Boolean Ja decimal Decimal Ja string String Ja object Object Ja dynamic Object Ja 37 Primitive types byte of Byte?   Verwarrend (door geen/wel voorkennis)  String of string, Byte of byte, Boolean of bool?  int in 64-bit omgeving: 32 of 64 bits?  int mapt altijd naar int32, ongeacht de processor-architectuur!  Verschillende betekenis naargelang programmeertaal  long in C# : 64 bits  long in C++: 32 bits Ontwerpen van types 38 Overflows Wat is het resultaat van onderstaand codefragment?  byte b = 100; b = (byte)(b + 200); Console.WriteLine(b);  De waarde 300 past niet in type byte  overflow treedt op 39 Overflow “silent” overflow is vaak ongewenst   C en C++: géén error  Visual Basic: wél error CLR heeft specifieke IL-instructies voor checking   Bv.: add  add.ovf In C#: kiezen bij compilatie   Standaard: geen checking  sneller! 40 Overflow Mogelijk om specifieke blokken in code te checken:   Gebruik checked {} of unchecked {} checked { byte b = 100; b = (byte)(b + 200); Console.WriteLine(b); } 41 Overflow Overflow - conclusies   Gebruik signed data types (Int16, Int32, SByte…)  Gebruik expliciet checked rond code die externe gegevens ontvangt  Gebruik expliciet unchecked indien overflow OK is  Checking: globale instelling  Aan: tijdens ontwikkeling project. Verbeter overflow fouten.  Uit: in release versie van applicatie Ontwerpen van types 42 Reference Types & Value Types 43 Reference & Value Types CLR ondersteunt twee types   Reference Types  Variabele bevat referentie (verwijzing) naar object  Object wordt bewaard op de heap  Value Types  Variabele bevat de waarde zélf  Wordt opgeslagen op de stack 44 Reference & Value Types Demo Reference & Value Types  int leeftijd = 20; string naam = "Sam"; Variabele leeftijd: bevat waarde 14 (hex) = 20 (dec) Variabele naam: bevat verwijzing naar string-object 45 Reference & Value Types Class   Reference type System.Object  Kan erven van baseclass  Kan dienen als baseclass (tenzij sealed) class  Kan interface implementeren  Variabele bevat null of een pointer  Object wordt op de heap geplaatst (zorgt voor overhead!)  Geheugen moet gealloceerd worden op de heap  Alle bytes moeten geïnitialiseerd worden met 0  Extra members moeten geïnitialiseerd worden (type object pointer & sync block index)  Allocatie op de heap heeft soms garbage collection tot gevolg 46 Reference & Value Types System.Object System.ValueTyp Struct  e  Value type struct  Kan niet erven van baseclass (behalve van System.ValueType)  Kan niet dienen als basetype  Kan interface implementeren  De variabele kan geen null bevatten (oplossing: Nullable types)  Bestaat in twee vormen: boxed en unboxed (zie later) 47 Reference & Value Types System.Object System.ValueTyp Struct (vervolg)  e  Erft van ValueType en erft dezelfde methoden struct  Overrides Equals (zodat alle members vergeleken worden)  Override GetHashCode (zodat hash bepaald wordt door alle members)  Methods zijn per definitie sealed (geen virtual, abstract of overrides mogelijk)  De variabele bevat de data (= waarde (= value))  Als variabele in methode gedeclareerd staat, wordt ze op de stack gealloceerd  Alle bytes worden geïnitialiseerd met 0  Geen extra members moeten geïnitialiseerd worden  Geen allocatie op de heap  geen garbage collection 48 Reference & Value Types System.Object Enum   Speciale vorm van ValueType System.ValueTyp e System.Enum enum 49 Reference & Value Types Bron: https://flylib.com/books/en/4.253.1.28/1/ 50 Boxing & Unboxing 51 Wat is Boxing? Boxing   Value-type  Lichtgewicht t.o.v. reference type  Geen geheugen nodig op heap  Geen pointer naar dit geheugen  Geen garbage collection nodig Vaak is er echter een reference nodig naar een instantie van een value-type 52 Wat is Boxing?  Boxing is het proces waarbij een value-type (zoals int, float, bool, etc.) wordt omgezet in een reference-type  Value-types worden normaal gezien opgeslagen op de stack  De waarde van het waarde-type wordt gekopieerd naar een object op de heap  De referentie naar dit nieuwe object (op de heap) wordt vervolgens teruggegeven 53 Wat is Boxing? Voorbeeld boxing:  int x = 123; // Waarde-type, opgeslagen op de stack object obj = x; // Boxing: de waarde van x wordt gekopieerd naar de heap als een object 54 Wat is Unboxing? Unboxing is het omgekeerde van boxing   Een boxed waarde-type wordt terug omgezet naar een waarde-type  Waarde wordt uit object op heap gehaald en opnieuw op stack gezet Proces bestaat uit twee stappen:  1. Verifiëren dat het object werkelijk een boxed waarde-type bevat van het juiste type 2. Het uitlezen van de waarde uit het object en deze op de stack plaatsen 55 Wat is Unboxing? Voorbeeld unboxing:  object obj = 123; // Boxing: int 123 wordt opgeslagen als een object op de heap int y = (int)obj; // Unboxing: het boxed object wordt terug omgezet naar een int 56 Performance-issues Opgelet: boxing en unboxing kunnen een negatieve impact  hebben op de performantie van de code  Boxing vereist geheugenallocatie op de heap. Het aanmaken van objecten op de heap is “duurder” dan het werken met waarde- types op de stack.  Unboxing introduceert extra werk omdat de CLR moet controleren of het object het juiste type bevat en vervolgens de waarde moet ophalen. Onnodige (un)boxing vermijden:   Gebruik ildasm.exe  Gebruik generics (ipv object-parameters) 57 Dynamic 58 Dynamic C# is type safe language   Elke expressie resulteert in een gekend type  Compiler genereert enkel code voor geldige operaties op het type  Voordelen:  Veel fouten worden gedetecteerd at compile-time  Kleinere en snellere code (minder checks at runtime nodig) Ontwerpen van types 59 Dynamic Gebruiken van in compiletime onbekende informatie:   Via reflection  Vaak complexe code  Traag  Via dynamic  NIET hetzelfde als var!  Indien een member wordt aangesproken van een dynamic expressie/variabele, genereert de compiler speciale IL code die de gewenste operatie beschrijft. Dit noemt men de payload. Deze payload code zal at runtime bepalen welke operatie moet uitgevoerd worden op basis van het actuele objecttype. Ontwerpen van types 60

Use Quizgecko on...
Browser
Browser