Collections i C#

Enum i C#

Hvad er Enum?

Enum er kort for enumeration, som er en brugerdefineret værditype, og værdien er så en konstant.

Syntaks for Enum:

enum [Navn]

{

        [Konstant1],

        [Konstant2],

        [Konstant3],

        …

}

Anvendelse af Enum

// Define an enum for seasons
enum Season
{
    Spring,
    Summer,
    Autumn,
    Winter
}

class Program
{
    static void Main()
    {
        // Use the enum
        Season currentSeason = Season.Spring;
        
        // Comparison with enum values
        if (currentSeason == Season.Summer)
        {
            Console.WriteLine("Don't forget sunscreen!");
        }
        
        // Conversion between enum and integer
        int seasonNumber = (int)currentSeason;  // 0 for Spring
        Console.WriteLine($"Season number: {seasonNumber}");
        
        // Conversion from integer to enum
        Season convertedSeason = (Season)2;  // Autumn
        Console.WriteLine($"Converted season: {convertedSeason}");
        
        // Get all values from an enum
        foreach (Season season in Enum.GetValues(typeof(Season)))
        {
            Console.WriteLine(season);
        }
    }
}

Dette eksempel benytter sig af type casting (typekonvertering på dansk), hvor man “tvinger” en værdi til at skifte værditype.


Dette kan gøres ved:

int seasonNumber = (int)currentSeason;

eller:

double pi = 3.14;
int piAsInt = Convert.ToInt32(pi);
Console.WriteLine(piAsIntUsingConvert); // Udskriver: 3

Enum med Eksplicitte Værdier

Enum-konstanter har automatisk værdier, der starter på 0 og går op med 1.

Men konstanerne kan også gives specifikke værdier, fx

{

Sunday = 1,

Monday = 2,

Tuesday = 3,

Wednesday = 4,

Thursday = 5,

Friday = 6,

Saturday = 7

} // Her tildeles specifikke værdier til hver enum konstant.

Arrays i C#

En grundlæggende collection-type i C#.

Et array er en samling af værdier med samme datatype, der via et indeks kan tilgås, hvilket gør det let at gemme og manipulere grupper af relaterede data.

Arrays størrelse er fast og bestemmes ved oprettelsen.

Erklæring af et array

Angiv datatype og størrelse:

int[] numbers = new int[5]; // Et array af 5 integer

Initialisering af et array

int[] numbers = {1, 2, 3, 4, 5}; // Et array med værdierne 1, 2, 3, 4 og 5

Tilgang til elementer i et array

Elementernes tilgås vha. indekset, som starter ved 0

int firstNumber = numbers[0]; // Henter den første værdi i arrayet (1)
numbers[2] = 10; // Ændrer værdien af det tredje element til 10

Eksempel på brug af et array

using System;

class Program
{
    static void Main()
    {
        // Erklæring og initialisering
        int[] numbers = {1, 2, 3, 4, 5};
        
        // Udskrivning af elementer i arrayet
        for (int i = 0; i < numbers.Length; i++)
        {
            Console.WriteLine(numbers[i]);
        }
        
        // Ændring af et element
        numbers[2] = 10;
        
        // Udskrivning efter ændring
        Console.WriteLine("Efter ændring:");
        foreach (int number in numbers)
        {
            Console.WriteLine(number);
        }
    }
}

Array-metoder

int[] numbers = { 5, 2, 8, 1, 3 };
Array.Sort(numbers); // Sorterer arrayet i stigende rækkefølge
Array.Reverse(numbers); // Vender rækkefølgen af elementerne i arrayet
int index = Array.IndexOf(numbers, 3); // Finder indekset for tallet 3
bool contains = numbers.Contains(3); // Tjekker om 3 findes i arrayet

Multidimensionelle arrays

Med multifunktionelle arrays kan man opbevare data i flere dimensioner, fx 2D, 3D eller mere.

Der findes to typer multidimensionelle arrays i C#:

  1. Rektangulære arrays (jagged arrays)

  2. Flerdimensionelle arrays

Rektangulære arrays (jagged arrays)

Et jagged array er et array af arrays, hvor hver "under-array" kan have en forskellig længde, hvilket giver mere fleksibilitet og kan være mere hukommelseseffektivt i visse situationer.

// Deklaration af et jagged array
int[][] jaggedArray = new int[3][];

// Initialisering af de indre arrays
jaggedArray[0] = new int[] { 1, 2, 3 };
jaggedArray[1] = new int[] { 4, 5 };
jaggedArray[2] = new int[] { 6, 7, 8, 9 };

// Alternativ syntaks
int[][] jaggedArray = new int[][]
{
    new int[] { 1, 2, 3 },
    new int[] { 4, 5 },
    new int[] { 6, 7, 8, 9 }
}

Flerdimensionelle arrays

Flerdimensionelle arrays har et fast antal dimensioner og en fast størrelse i hver dimension:

// 2D array (tabel)
int[,] matrix = new int[3, 4];  // 3 rækker, 4 kolonner

// Initialisering af et 2D array
int[,] matrix = new int[3, 4]
{
    { 1, 2, 3, 4 },
    { 5, 6, 7, 8 },
    { 9, 10, 11, 12 }
};

Iterering gennem multidimensionelle arrays

// Iterering gennem et jagged array
for (int i = 0; i < jaggedArray.Length; i++)
{
    for (int j = 0; j < jaggedArray[i].Length; j++)
    {
        Console.WriteLine($"jaggedArray[{i}][{j}] = {jaggedArray[i][j]}");
    }
}

// Iterering gennem et 2D array
for (int i = 0; i < matrix.GetLength(0); i++)
{
    for (int j = 0; j < matrix.GetLength(1); j++)
    {
        Console.WriteLine($"matrix[{i}, {j}] = {matrix[i, j]}");
    }
}

Forskel på et jagged array og et 2D-array

Et jagged array er et array af arrays, hvor hver underarray kan have forskellig længde, mens et 2D-array har en fast størrelse og alle rækkerne har den samme længde.

Et 2D-array har en fast hukommelse, mens et jagged array ikke har en sammenhængende hukommelse.

Egenskab

2D-array

Jagged array

Sammenhængende hukommelse

Ja

Nej

Adgangshastighed

Hurtigere

🔸 Lidt langsommere

Fleksibilitet i størrelse

Nej (fast størrelse)

Ja (hver række kan variere)

Hukommelsesstruktur

Én blok

Flere adskilte blokke

List i C#

Hvad er List<T>?

List<T> er en del af System.Collections.Generic-namespace, og er en generisk, dynamisk collection.

List<T> kan - i modsætning til et array - vokse og krympe dynamisk efter behov.

T er et typeparameter, der angiver datatypen af elementer, som listen kan indeholde. Derfor skal den ‘byttes ud’ med fx int, string eller en klasse (fordi objekter fra en klasse er sin egen datatype).

Oprettelse af List<T>

En List kan oprettes på forskellige måder:

// Creation of an empty list of integers
List<int> numberList = new List<int>();

// Creation with initialization
List<string> nameList = new List<string>() { "Alice", "Bob", "Charlie" };

// Creation with initial capacity
List<double> decimalList = new List<double>(10);

Grundlæggende List<T> Operationer

List<string> fruits = new List<string>();

// Add elements
fruits.Add("Apple");
fruits.Add("Banana");
fruits.Add("Orange");

// Insert an element at a specific position
fruits.Insert(1, "Pear");  // ["Apple", "Pear", "Banana", "Orange"]

// Remove an element
fruits.Remove("Banana");  // ["Apple", "Pear", "Orange"]

// Remove element by index
fruits.RemoveAt(0);  // ["Pear", "Orange"]

// Check if an element exists
bool contains = fruits.Contains("Pear");  // true

// Find the number of elements
int count = fruits.Count;  // 2

// Sort the list (alphabetically)
fruits.Sort();  // ["Orange", "Pear"]

// Reverse the order of the list
fruits.Reverse();  // ["Pear", "Orange"]

// Clear the list
fruits.Clear();  // []

Iteration gennem List<T>

Iterationer gennem en List kan foregå således:

List<string> names = new List<string>() { "Alice", "Bob", "Charlie", "David" };

// Using foreach
foreach (string name in names)
{
    Console.WriteLine(name);
}

// Using for-loop with index
for (int i = 0; i < names.Count; i++)
{
    Console.WriteLine($"{i}: {names[i]}");
}

{i}: {names[i]} udskriver navnene, hvor i er indekset (altså pladsen), og names[i] er navnet på den plads.

(Notér kolon er bare kolon)

Så der vil stå 1: Anna osv.

List<T> vs. Arrays

Fordele ved List<T>:

  • Dynamisk størrelse

  • Mange indbyggede metoder

  • Nemmere at arbejde med (tilføj, fjjern, find etc)

Fordele ved Arrays:

  • Lidt bedre ydeevne

  • Mindre hukommelsesforbrug

  • Mulighed for flere dimensioner

Modellering af Collections i Klassediagrammer

  • Multiplicitet (kardinalitet)

  • Relationer (associering, aggregering og komposition)

Multiplicitet i UML

  • 1: Præcis én

  • 0..1: Nul eller én

  • *: Mange (nul eller flere)

  • 1..: Mindst én

  • n: Præcis n

  • n..*: Fra n til mange

Associering

Associering beskriver en relation mellem to klasser, hvor deres objekter eksisterer uafhængigt af hinanden.

Det er en simpel relation, hvor objekter af den ene klasse er forbundet med objekter fra den anden, og relationen vises med en simpel linje mellem klasserne i UML.

Multipliciteten kan være mange-til-mange (*), en-til-mange (1..*) eller en-til-en (1).

Associering og multiplictet afhænger af, hvordan systemet er skruet sammen og fungerer.

Implementering af associering relation

using System;
using System.Collections.Generic;

class Student
{
    public string Name { get; set; }
}

class Course
{
    public string Title { get; set; }
    // Association - a list of students taking the course
    public List<Student> Participants { get; set; }
    
    // Constructor to initialize the list
    public Course()
    {
        Participants = new List<Student>();
    }
    
    // Method to add a student to the course
    public void AddStudent(Student student)
    {
        Participants.Add(student);
    }
    
    // Method to display all students in the course
    public void DisplayStudents()
    {
        Console.WriteLine($"Students enrolled in {Title}:");
        foreach (var student in Participants)
        {
            Console.WriteLine($"- {student.Name}");
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Create a course
        Course programmingCourse = new Course
        {
            Title = "C# Programming"
        };
        
        // Create some students
        Student student1 = new Student { Name = "John Smith" };
        Student student2 = new Student { Name = "Emma Johnson" };
        Student student3 = new Student { Name = "Michael Brown" };
        
        // Add students to the course
        programmingCourse.AddStudent(student1);
        programmingCourse.AddStudent(student2);
        programmingCourse.AddStudent(student3);
        
        // Display all students in the course
        programmingCourse.DisplayStudents();
    }
}

Aggregering

Aggregering repræsenterer et ‘har-en’ relation. Det er en svag form for ejerskab, hvor de igen kan eksisterer uafhængigt af hinanden (den indeholdte klasse og container-klassen).

Aggregering vises med en tom diamant på container-enden af relationen.

Eksempler på aggregering i C# omfatter klasser som Library og Book, hvor Library kan eksistere uden Book, men en Book kan også eksistere uafhængigt af Library. I et diagram ville dette blive vist med en tom diamant ved siden af Library, der indikerer relationen.

Implementering af aggregering relation

using System;
using System.Collections.Generic;

class Team
{
    public string Name { get; set; }
    public List<Player> Players { get; set; } = new List<Player>();
}

class Player
{
    public string PlayerName { get; set; }
}

class Program
{
    static void Main()
    {
        Team team = new Team { Name = "Red Warriors" };
        Player player = new Player { PlayerName = "John" };
        team.Players.Add(player);
    }
}

Komposition

En stærk form for ejerskabsrelation, hvor den indeholdte klasse er en integreret del af container-klassen og ikke kan eksistere uden den.

Komposition vises med en fyldt diamant på container-enden af relationen.

Implementering af komposition-relation

using System;
using System.Collections.Generic;

class House
{
    public List<Room> Rooms { get; private set; } = new List<Room>();
    
    public House()
    {
        Rooms.Add(new Room("Living Room"));
        Rooms.Add(new Room("Bedroom"));
    }
}

class Room
{
    public string RoomName { get; private set; }
    public Room(string name) { RoomName = name; }
}

class Program
{
    static void Main()
    {
        House house = new House();
    }
}