Egenskaper
Properties är som smarta dörrvakter för dina klassvariabler! De kontrollerar vem som får komma in, vad de får göra, och håller ordning på allt. Ingen mer anarchy med publika fields! 🚪✋
🎯 Efter denna artikel kommer du att:
- Förstå properties vs fields - skillnaden mellan rå data och kontrollerad access 🔒
- Skapa properties i alla stilar - från gammal stil till modern C-Sharp 14 ✨
- Använda init-only properties - sätt en gång, använd för evigt! 🔧
- Hantera computed properties - värden som beräknas on-the-fly 🧮
📊 Evolution of Properties - Från Stenåldern till C-Sharp 14
🏺 Stenåldern: Public Fields (Gör ALDRIG detta)
// ❌ GAMMAL & FARLIG - ingen kontroll!
public class BadBankAccount
{
public decimal balance; // Vem som helst kan sätta vad som helst!
}
// Somewhere else in code:
var account = new BadBankAccount();
account.balance = -1000000; // 💸 BANKRUPTCY! Ingen kan stoppa oss!
🏛️ Klassisk Epok: Full Properties (C-Sharp 1.0)
// ✅ KLASSISK - full kontroll men verbose
public class ClassicBankAccount
{
private decimal _balance; // Private field - the real data
// Full property with validation
public decimal Balance
{
get
{
Console.WriteLine($"🔍 Balance requested: {_balance}");
return _balance;
}
set
{
if (value < 0)
throw new ArgumentException("❌ Saldot kan inte vara negativt!");
Console.WriteLine($"💰 Setting balance from {_balance} to {value}");
_balance = value;
}
}
}
🏢 Modern Epok: Auto-Properties (C-Sharp 3.0)
// ✅ MODERN - kortare men fortfarande kraftfull
public class ModernBankAccount
{
// Auto-property - compiler skapar private field automatically
public decimal Balance { get; set; }
// Auto-property med validation
private decimal _balance;
public decimal ValidatedBalance
{
get => _balance;
set => _balance = value >= 0 ? value : throw new ArgumentException("❌ Negativt saldo!");
}
// Read-only auto property
public string AccountNumber { get; private set; }
// Get-only computed property
public string DisplayBalance => $"{Balance:C} SEK";
}
🚀 Futuristisk Era: Init-Only Properties (C-Sharp 9+)
// ✅ C-Sharp 14 STYLE - immutable by default!
public class FuturisticBankAccount
{
// Init-only - can only be set during construction
public string AccountNumber { get; init; } = string.Empty;
public string Owner { get; init; } = string.Empty;
public DateTime CreatedDate { get; init; } = DateTime.Now;
// Regular property for things that change
public decimal Balance { get; set; }
// Required property - must be set during construction
public required string Bank { get; init; }
// Computed property with expression body
public string AccountInfo => $"🏦 {Bank}: {AccountNumber} ({Owner})";
// Complex computed property
public string BalanceStatus => Balance switch
{
< 0 => "🔴 Skuld",
< 1000 => "🟡 Lågt saldo",
< 10000 => "🟢 Normalt saldo",
_ => "💎 Rik person!"
};
}
🔒 Property Access Levels - Vem Får Göra Vad?
public class SecurityExample
{
// Public get/set - alla kan läsa och skriva
public string PublicData { get; set; } = "Everyone can access";
// Public get, private set - alla kan läsa, bara denna class kan skriva
public string ReadOnlyForOthers { get; private set; } = "Read-only outside";
// Public get, protected set - alla kan läsa, bara denna class + barn kan skriva
public string ReadOnlyForPublic { get; protected set; } = "Family can write";
// Public get, init set - alla kan läsa, bara constructor kan skriva
public string SetOnceOnly { get; init; } = "Set during construction only";
// Private property - bara denna class
private string SecretData { get; set; } = "Top secret";
// Protected property - bara denna class + barn
protected string FamilySecret { get; set; } = "Family only";
public void DemonstrateAccess()
{
// Denna class kan göra allt
PublicData = "Changed by owner";
ReadOnlyForOthers = "Owner can change";
ReadOnlyForPublic = "Owner can change";
SecretData = "Owner knows all secrets";
FamilySecret = "Owner shares with family";
// SetOnceOnly kan INTE ändras här - bara i constructor/init!
// SetOnceOnly = "Nope!"; // ❌ Compilation error
}
}
public class SecurityChild : SecurityExample
{
public void ChildAccess()
{
// Child class kan accessa protected
FamilySecret = "Child changed family secret";
ReadOnlyForPublic = "Child can write this";
// Men inte private
// SecretData = "Nope!"; // ❌ Not accessible
}
}
🎯 Property Patterns - When to Use What
📋 Decision Matrix
| Scenario | Property Type | Example |
|---|---|---|
| Simple data storage | Auto-property | public string Name { get; set; } |
| Read-only data | Init-only | public string Id { get; init; } |
| Computed value | Expression body | public string FullName => $"{First} {Last}" |
| Validated input | Full property | Custom getter/setter with validation |
| Expensive calculation | Lazy/cached | Cache result, recalculate when needed |
| Must be set | Required | public required string Name { get; init; } |
✅ Property Best Practices
public class BestPracticeExample
{
// ✅ Use init for immutable data
public required string Id { get; init; }
// ✅ Use auto-properties for simple data
public string Name { get; set; } = string.Empty;
// ✅ Use expression bodies for computed properties
public string DisplayName => string.IsNullOrEmpty(Name) ? "Unknown" : Name;
// ✅ Use validation in setters when needed
private int _age;
public int Age
{
get => _age;
set => _age = value >= 0 ? value : throw new ArgumentException("Age cannot be negative");
}
// ✅ Use private setters for controlled access
public DateTime CreatedAt { get; private set; } = DateTime.Now;
// ✅ Use collections with private setters
public List<string> Tags { get; private set; } = [];
public void AddTag(string tag)
{
if (!string.IsNullOrEmpty(tag))
Tags.Add(tag);
}
}
💡 Marcus Property Wisdom
“Properties är som att hyra ut lägenhet - du vill ha kontroll över vem som kommer in, vad de gör där, och att de städar efter sig! Ingen vill ha en lägenhet där vem som helst kan komma och gå som de vill!” 🏠🔑
Real story: 2019 debuggade jag en bug i 3 dagar som visade sig vara att någon satte ett negativt värde direkt på en public field. Efter det: INGA fler public fields, bara properties med validation! 😅
Pro tip: Börja alltid med auto-properties. Uppgradera till full properties bara när du behöver validation eller custom logic. YAGNI (You Ain’t Gonna Need It) gäller här också! 🚀
Ready för Constructors och Records? Properties är grunden - nu bygger vi objekt som proffs! 🏗️