Konstruktorer

Constructors är som digitala arkitekter som bygger dina objekt från grunden! De bestämmer vad som händer när du säger new MyClass() - ingen mer slumpmässigt initialiserade objekt! 🏠⚡

🎯 TL;DR

Constructors = objekt-byggare. Static properties = klass-level data. Const vs readonly = kompilerings-konstanter vs runtime-konstanter. Records = automatiska value-objects. Enums = namngivna konstanter. Allt för att bygga robusta, välorganiserade klasser!

🎯 Efter denna artikel kommer du att:

  • Behärska alla constructor-typer - default, parameterized, copy, static 🔨
  • Förstå static properties vs instance properties - klass-data vs objekt-data 📊
  • Veta skillnaden mellan const och readonly - kompilering vs runtime 🔒
  • Använda enums professionellt - namngivna konstanter som rocks 🏷️
  • Skapa moderna records - automatic value objects med C-Sharp 14 syntax 📦
  • Designa robusta klass-hierarkier - från grund till avancerat 🏛️

🏗️ Alla Constructor-Typer - Komplett Guide

🎯 Decision Matrix - Vilken Constructor ska jag använda?

ScenarioConstructor TypeNär använd
Enkel initDefault (parameterlös)Objekt kan vara giltigt utan extra data
Kräv dataParameterizedDu måste validera eller kräva specifik data
FlexibilitetÖverlagradeFlera init-vägar (basic vs advanced setup)
Modern stilPrimary Constructor (C-Sharp 12+)Minimal boilerplate, record-lik smidighet
SingletonPrivate ConstructorKontrollera objektskapande
Kopiera objektCopy ConstructorDuplicera befintligt objekt
Klass-initStatic ConstructorInitiera statiska resurser en gång

2. Parameterized Constructor - Kräv Data


public class Player
{
    public string Name { get; }
    public int Level { get; private set; }
    public DateTime JoinDate { get; }

    // Parameterized constructor med validation
    public Player(string name, int level)
    {
        // Validera parametrar FÖRST
        if (string.IsNullOrWhiteSpace(name))
            throw new ArgumentException("❌ Player name cannot be empty!");

        if (level < 1 || level > 100)
            throw new ArgumentOutOfRangeException(nameof(level), "❌ Level must be 1-100");

        Name = name;
        Level = level;
        JoinDate = DateTime.Now;

        Console.WriteLine($"✅ Player {Name} created at level {Level}!");
    }
}

// Usage - MÅSTE ge parametrar
var player = new Player("Marcus", 42);

🚀 4. Primary Constructor (C-Sharp 12+) - Modern Magic


// Primary constructor - parametrar i class declaration!
public class User(string name, string email, int age)
{
    public string Name { get; } = name ?? throw new ArgumentNullException(nameof(name));
    public string Email { get; } = IsValidEmail(email) ? email : throw new ArgumentException("Invalid email");
    public int Age { get; } = age >= 0 ? age : throw new ArgumentException("Age cannot be negative");

    public string DisplayName => $"{Name} ({Age} years old)";

    // Validation method
    private static bool IsValidEmail(string email) =>
        !string.IsNullOrEmpty(email) && email.Contains('@');

    public override string ToString() => $"{Name} <{Email}>";
}

// Usage - clean och modern!
var user = new User("Marcus", "marcus@example.com", 35);
Console.WriteLine(user.DisplayName);

🏭 6. Singleton Pattern med Private Constructor


public sealed class Logger
{
    // Lazy initialization - skapas först när den behövs
    private static readonly Lazy<Logger> _instance = new(() => new Logger());

    public static Logger Instance => _instance.Value;

    // Private constructor - förhindrar multiple instances
    private Logger()
    {
        Console.WriteLine("📝 Logger initialized - this happens only ONCE!");
    }

    public void Log(string message)
    {
        var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        Console.WriteLine($"[{timestamp}] {message}");
    }
}

// Usage - samma instans överallt!
Logger.Instance.Log("Application started");
Logger.Instance.Log("User logged in");

var logger1 = Logger.Instance;
var logger2 = Logger.Instance;
Console.WriteLine($"Same instance? {ReferenceEquals(logger1, logger2)}"); // True!

⚙️ 8. Static Constructor - Klass-Level Init


public class GameConfiguration
{
    public static Dictionary<string, int> DefaultStats { get; private set; }
    public static string[] AvailableClasses { get; private set; }
    public static DateTime ServerStartTime { get; private set; }

    // Static constructor - körs EN GÅNG när klassen först används
    static GameConfiguration()
    {
        Console.WriteLine("🔧 Initializing game configuration...");

        // Ladda default stats
        DefaultStats = new Dictionary<string, int>
        {
            ["Warrior"] = 100,
            ["Mage"] = 60,
            ["Archer"] = 80,
            ["Healer"] = 70
        };

        // Ladda available classes
        AvailableClasses = DefaultStats.Keys.ToArray();

        ServerStartTime = DateTime.Now;

        Console.WriteLine($"✅ Game config loaded with {DefaultStats.Count} classes");
    }

    // Regular static method
    public static int GetDefaultHealth(string className)
    {
        return DefaultStats.TryGetValue(className, out var health) ? health : 50;
    }
}

// Usage - static constructor körs automatiskt vid första användning
Console.WriteLine($"Warrior health: {GameConfiguration.GetDefaultHealth("Warrior")}");
// Output:
// 🔧 Initializing game configuration...
// ✅ Game config loaded with 4 classes
// Warrior health: 100

😄 Obligatorisk Dad Joke

Varför gillar constructors aldrig överraskningar?

För att de vill alltid veta exakt vad de bygger från början! 🏗️😄

“Hej, jag är Constructor. Jag tar dina parametrar och bygger something awesome!”


Upp

Upp


Licens: Apache 2.0 | © 2023 Marcus Medina, Campus Mölndal. Alla rättigheter förbehållna.
Du får använda och modifiera detta verk enligt villkoren i Apache License, Version 2.0. Du får inte använda detta verk för kommersiella ändamål utan tillstånd från upphovsmannen.