[G_PRO] Basis Programmeren en OO Programmeren
DigitAP
  • Welkom
  • Inleiding
    • Benodigdheden
    • Afspraken code
    • Afspraken oefeningen
    • Nuttige extras
    • Dankwoord
    • Mee helpen?
  • Semester 1: Programming Principles
    • H1: Werken met Visual Studio
      • Introductie tot C#
      • Visual Studio en .NET Core installeren
      • Een C# project maken in Visual Studio
      • Fouten in je code
      • Je eerste stappen in C#
      • Input/Output: ReadLine/WriteLine
      • Kleuren in Console
      • Oefeningen
    • H2: Variabelen en datatypes
      • De syntaxis van C#
      • Datatypes
      • Variabelen
      • Expressies en operators
      • Oefeningen
    • H3: Strings en hun methoden
      • Strings
      • Strings samenvoegen
      • Omzetten van en naar strings
      • Functionaliteit van strings
      • Oefeningen
    • H4: Beslissingen
      • Beslissingen intro
      • Enkelvoudige booleaanse expressies
      • If, else, else if
      • Samengestelde booleaanse expressies
      • Scope van variabelen
      • Switch
      • Oefeningen
    • H5: Loops
      • Loops intro
      • While en Do While
      • For
      • Debuggen
      • Oefeningen
    • H6: Arrays
      • Array principes
      • Alternatieve syntax
      • Werken met arrays
      • Defaultwaarden
      • List<T>
      • Oefeningen
    • H7: Methoden
      • Methoden intro
      • Parameters
      • Return waarden
      • Geavanceerde methoden
      • Oefeningen
    • Intermezzo: TextCell
    • H8: Numerieke data
      • De Math klasse
      • Random
      • Casting en conversie
      • Oefeningen
    • H9: Meerdimensionaal werken
      • N-dimensionale arrays
      • Geneste iteratie
      • Oefeningen
    • H10: Gevorderde tekstverwerking
      • Voorstelling van tekst
      • Interpolatie met formattering
      • Werken met arrays van strings
      • Input en output van tekstbestanden
      • Oefeningen
    • Afsluiter: TextCell2D
  • Semester 2 : OOP
    • H10: Klassen en objecten
      • OOP Intro
      • Klassen en objecten aanmaken
      • DateTime: leren werken met objecten
      • Enumeraties: nog een eigen datatype
      • Klassen en objecten weergeven deel 1
      • Attributen
      • Methoden
      • Access modifiers
      • Properties
      • Oefeningen
    • H11: Objecten (al dan niet) aanmaken
      • Constructors
      • Spelen met strings
      • Oefeningen
    • H12: Geheugenmanagement bij klassen
      • value en reference met eigen objecten
      • nullable value types
      • NullReference exception
      • Oefeningen
    • H13: Datastructuren
      • Foreach en var
      • List
      • Dictionary
      • Immutable datastructuren
      • Verdere datastructuren
      • Oefeningen
    • H14: Overerving
      • Overerving intro
      • Virtual en override
      • Abstract
      • Constructors bij overerving
      • Oefeningen
    • H15: Geavanceerde overerving
      • protected access modifier
      • Base keyword
      • System.Object
      • Oefeningen
    • H16: Exception handling
      • Werken met exceptions
      • Zelf uitzonderingen maken
      • Wanneer exceptions en handling gebruiken
      • Oefeningen
    • H17: Polymorfisme en interfaces
      • Polymorfisme
      • Polymorfisme in de praktijk
      • Interfaces
      • Losse koppeling
      • Oefeningen
    • H18: Testing
      • Intro Testing
      • Wat is Unit Testing
      • Waarom Unit Testing?
      • Wanneer Unit Testing?
      • Schrijven van een unit test: AAA methode
      • Eerste voorbeeld: Sum
      • Assert
      • Oefening even of oneven getal
      • TestInitialize en DataRows
      • Oefening BMI
      • Exception testing
      • Oefening BMI exception
      • Oefening SchoolAdmin test null-waarden en TestCleanup
      • Oefening SchoolAdmin test equals
      • Oefening SchoolAdmin test cursus zoeken met id
      • Dependencies bij Unit Testing
      • Mocking
      • Oefeningen Mocking
      • Test Driven Development
      • Class Library
      • Oefeningen TDD
    • H19: SOLID
      • Single Responsibility Principle (SRP)
      • Open/Closed Principle (OCP)
      • Liskov Substitution Principle (LSP)
      • Interface Segregation Principle (ISP)
      • Dependency Inversion Principle (DIP)
  • Appendix
    • Visual Studio Tips & Tricks
    • Ea-ict coding guidelines
    • Oefeningen kerkhof
  • Semester 1 appendix
    • Nice to know stuff
      • Out en Ref parameters
      • Jagged arrays
    • All-In-Projecten
      • Overzicht
      • Console Matrix
      • Ascii filmpjes maken met loops
      • Ascii filmpjes maken met methoden
      • Fun with methods: een verhaalgenerator
      • Tekst-gebaseerd Maze game
      • Conway game of life
  • Semester 2 appendix
    • Operator overloading
    • Object Initializer Syntax
    • Compositie en aggregatie
    • Nice to know stuff
      • Klassen herbruiken
      • Expression bodied members
    • All-In-Projecten
      • Overzicht
      • OO Textbased Game
      • War Simulator
      • Map Maker
      • Magic The Gathering API
      • SchoolAdmin
  • Pro (geen leerstof en/of in opbouw)
    • Bitwise operators
    • Generics en collections
      • Generics methoden en types
      • Generic classes en constraints
      • Collections
      • Labo-oefeningen
    • Events
      • Events
      • Chat server
    • Software engineering
      • SOLID
Powered by GitBook
On this page
Export as PDF
  1. Semester 2 : OOP
  2. H13: Datastructuren

Immutable datastructuren

PreviousDictionaryNextVerdere datastructuren

Last updated 1 year ago

De standaard datastructuren van C# zijn . Dit betekent dat iedereen die zo'n datastructuur te pakken krijgt (bijvoorbeeld omdat je hem als argument meegeeft aan een methode), de inhoud van deze datastructuur ook kan wijzigen. Dit kan met opzet of gewoonweg per vergissing gebeuren.

Hoezo, "met opzet"? Denk eraan dat je typisch niet de enige programmeur bent die met bepaalde code in contact komt.

Bijvoorbeeld:

// je gebruikt deze methode in de veronderstelling dat ze je data alleen maar print
// maar, zonder dat je het daarom meteen merkt, wist ze ook data
public static void PrintData(List<string> data) {
    for (int i = 0; i < data.Count; i++) {
        Console.WriteLine(data[i]);
        data[i] = null;
    }
}

In het algemeen geldt: als iemand bepaalde mogelijkheden niet echt nodig heeft, geef ze dan niet. Dit is opnieuw encapsulatie.

Om te verhinderen dat een datastructuur wordt aangepast, kan je er een immutable versie van maken. Dit is een versie van die datastructuur waarvan de inhoud achteraf niet gewijzigd kan worden. Er bestaan immutable versies van de standaard datastructuren en ze heten gewoonweg ImmutableList<T> en ImmutableDictionary<K,V>.

Om deze versies te gebruiken, moet je de System.Collections.Immutable namespace gebruiken. Wanneer je hier een using directief voor hebt staan, kan je methodes zoals ToImmutableList<T> oproepen op een lijst om er een immutable versie van te produceren. Deze immutable versie kan je dan veilig delen met code waarvan je niet wenst dat ze de inhoud van je lijst aanpast.

Een tweede manier om een immutable datastructuur te maken, is met een builder. Dit is een object waar je via Add data aan toevoegt en dat je achteraf vraagt een immutable list te produceren. Je kan er een aanmaken met de statische methode CreateBuilder van de immutable datastructuur die je wil gebruiken. Bijvoorbeeld:

public static void PrintData(ImmutableList<string> data) {
    foreach(var datum in data) {
        Console.WriteLine(datum);
    }
}

public static void DemonstreerImmutableListBuilder() {
    var builder = ImmutableList.CreateBuilder<string>();
    bool doorgaan;
    do {
        Console.WriteLine("Geef een element om toe te voegen");
        builder.Add(Console.ReadLine());
        Console.WriteLine("Doorgaan met elementen toevoegen?");
        doorgaan = Console.ReadLine().ToLower() == "ja";
    } while (doorgaan);
    PrintData(builder.ToImmutableList<string>());
}

het verschil met read-only properties

Beginnende programmeurs denken soms dat ze hetzelfde effect kunnen verkrijgen door een property voor een datastructuur "read only" te maken. Dit doen ze dan door alleen een getter te voorzien en geen setter of, als ze buiten deze cursus gaan zoeken, met het sleutelwoordje readonly.

Dit maakt je datastructuur niet immutable! Het zorgt er wel voor dat je het object op de heap waarin je data staat niet kan vervangen. Het zorgt er niet voor dat je de inhoud van dat object niet kan vervangen.

Bijvoorbeeld, als we personen voorzien van een array met lievelingsgerechten:

class Persoon {

    private List<string> lievelingsgerechten;
    public List<string> Lievelingsgerechten {
        get {
            return this.lievelingsgerechten;
        }
    }
    
    public Persoon(string gerecht1, string gerecht2, string gerecht3) {
        this.lievelingsgerechten = new List<string>();
        this.lievelingsgerechten.Add(gerecht1);
        this.lievelingsgerechten.Add(gerecht2);
        this.lievelingsgerechten.Add(gerecht3);
    }
}

class Program {
    public static void Main() {
        var persoon = new Persoon("spaghetti","koekjes","ijs");
        // dit gaat WEL:
        persoon.Lievelingsgerechten[1] = "lasagne";
        persoon.Lievelingsgerechten.Add("frieten");
        foreach(var gerecht in persoon.Lievelingsgerechten) {
            Console.WriteLine(gerecht);
        }
        // dit gaat NIET:
        // persoon.Lievelingsgerechten = new List<string>();
    }
}

Onderstaande figuur toont een vereenvoudigde weergave van wat er aan de hand is:

reference types
Het is niet mogelijk de pijl van de persoon naar het lijstobject te vervangen. Het is wel mogelijk data in het lijstobject te veranderen.