Brugerdefinerede konverteringer
Tilføj implicitte og eksplicitte konverteringsoperatorer.
Brugerdefinerede konverteringer er en gratis C# Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i C# Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. C# Academy-kurset indeholder 4 lektioner i alt.
Brugerdefinerede konverteringer
C# lader en type definere, hvordan den konverterer til eller fra en anden type ved hjælp af operatorerne implicit og explicit. Implicitte konverteringer sker automatisk; eksplicitte kræver en typekonvertering.
En implicit konvertering
Brug implicit operator, når en konvertering altid er sikker og uden datatab. Kompilatoren anvender den automatisk overalt, hvor måltypen forventes.
using System;
public struct Celsius
{
public double Degrees;
public Celsius(double d) { Degrees = d; }
// Always safe: a Celsius is just a number
public static implicit operator double(Celsius c) => c.Degrees;
}
public class Program
{
public static void Main()
{
Celsius temp = new Celsius(21.5);
double d = temp; // implicit, no cast needed
Console.WriteLine(d);
}
}En eksplicit konvertering
Brug explicit operator, når en konvertering kan medføre datatab eller mislykkes. Den, der kalder koden, skal skrive en typekonvertering, hvilket signalerer, at vedkommende accepterer risikoen.
using System;
public struct Money
{
public decimal Amount;
public Money(decimal a) { Amount = a; }
// Loses the fractional cents, so make it explicit
public static explicit operator int(Money m) => (int)m.Amount;
}
public class Program
{
public static void Main()
{
var m = new Money(19.99m);
int dollars = (int)m; // explicit cast required
Console.WriteLine(dollars);
}
}Konvertering til din type
Konverteringer kan også gå den anden vej: fra en anden type til din type. Her opretter en implicit-operator en Celsius ud fra en rå double.
using System;
public struct Celsius
{
public double Degrees;
public Celsius(double d) { Degrees = d; }
public static implicit operator Celsius(double d) => new Celsius(d);
public override string ToString() => Degrees + "C";
}
public class Program
{
public static void Main()
{
Celsius t = 18.0; // double implicitly becomes Celsius
Console.WriteLine(t);
}
}Implicit eller eksplicit: Sådan vælger du
Tommelfingerreglen er: Gør konverteringen implicit, hvis den aldrig mister data og aldrig udløser en fejl. Hvis den kan miste præcision, give overflow eller mislykkes, skal den være eksplicit.
using System;
public struct Percentage
{
public double Value; // 0..1
public Percentage(double v) { Value = v; }
// Safe and lossless -> implicit
public static implicit operator double(Percentage p) => p.Value;
// Could be out of range -> explicit
public static explicit operator Percentage(double v) => new Percentage(v);
}
public class Program
{
public static void Main()
{
double d = new Percentage(0.25);
var p = (Percentage)0.5;
Console.WriteLine(d + " " + p.Value);
}
}Konverteringer mellem brugerdefinerede typer
Konverteringer er ikke begrænset til indbyggede typer. Du kan konvertere mellem to af dine egne typer, for eksempel fra polære til kartesiske koordinater.
using System;
public struct Cartesian
{
public double X, Y;
public Cartesian(double x, double y) { X = x; Y = y; }
public override string ToString() => "(" + Math.Round(X, 2) + ", " + Math.Round(Y, 2) + ")";
}
public struct Polar
{
public double R, Theta;
public Polar(double r, double theta) { R = r; Theta = theta; }
public static explicit operator Cartesian(Polar p)
=> new Cartesian(p.R * Math.Cos(p.Theta), p.R * Math.Sin(p.Theta));
}
public class Program
{
public static void Main()
{
var c = (Cartesian)new Polar(1.0, 0.0);
Console.WriteLine(c);
}
}Konverteringer fungerer sammen med operatorer
Når der findes en konvertering, kan værdien indgå i udtryk for måltypen. En implicit konvertering til double gør det muligt at bruge din type direkte i aritmetiske beregninger.
using System;
public struct Meters
{
public double Value;
public Meters(double v) { Value = v; }
public static implicit operator double(Meters m) => m.Value;
}
public class Program
{
public static void Main()
{
var distance = new Meters(5);
double doubled = distance * 2; // uses implicit conversion to double
Console.WriteLine(doubled);
}
}Undgå overraskende implicitte konverteringer
Implicitte konverteringer, der ikke tydeligvis er sikre, kan skjule fejl, fordi compileren anvender dem lydløst. Hvis du er i tvivl, så vælg en eksplicit konvertering, så hensigten er synlig i koden.
using System;
public struct UserId
{
public int Value;
public UserId(int v) { Value = v; }
// Explicit on purpose: an int is not always a valid id
public static explicit operator UserId(int v) => new UserId(v);
public static explicit operator int(UserId id) => id.Value;
}
public class Program
{
public static void Main()
{
var id = (UserId)42;
int raw = (int)id;
Console.WriteLine(raw);
}
}Konverteringsoperatorer er static
Ligesom andre operatorer er konverteringsoperatorer public static. Præcis én af de involverede typer skal være den type, der erklærer operatoren.
using System;
public struct Fahrenheit
{
public double Degrees;
public Fahrenheit(double d) { Degrees = d; }
public static implicit operator Fahrenheit(double d) => new Fahrenheit(d);
public static implicit operator double(Fahrenheit f) => f.Degrees;
public override string ToString() => Degrees + "F";
}
public class Program
{
public static void Main()
{
Fahrenheit f = 98.6;
double d = f;
Console.WriteLine(f + " = " + d);
}
}En praktisk wrapper-type
Konverteringer er særligt nyttige for tynde wrapper-typer, der styrker typesystemet uden at gøre brugen besværlig. Her konverteres en NonEmptyString implicit til string, men det kræver en eksplicit konvertering at oprette den.
using System;
public struct NonEmptyString
{
public string Value;
public NonEmptyString(string v)
{
if (string.IsNullOrEmpty(v)) throw new ArgumentException("empty");
Value = v;
}
public static explicit operator NonEmptyString(string s) => new NonEmptyString(s);
public static implicit operator string(NonEmptyString s) => s.Value;
}
public class Program
{
public static void Main()
{
var name = (NonEmptyString)"Ada";
string s = name;
Console.WriteLine(s);
}
}Prøv selv
Definér en wrapper med en implicit konvertering udad, som er sikker, og en eksplicit konvertering indad, som validerer værdien. Bemærk, hvilken retning der kræver en konvertering.
using System;
public struct Ratio
{
public double Value;
public Ratio(double v)
{
if (v < 0 || v > 1) throw new ArgumentOutOfRangeException(nameof(v));
Value = v;
}
public static implicit operator double(Ratio r) => r.Value; // always safe
public static explicit operator Ratio(double v) => new Ratio(v); // may throw
}
public class Program
{
public static void Main()
{
var half = (Ratio)0.5; // explicit, validated
double d = half; // implicit, safe
Console.WriteLine(d * 100 + "%");
}
}Hurtigt tjek
Vælg den rigtige type konvertering.
Opsummering
Brugerdefinerede konverteringer gør det nemt for dine typer at fungere sammen.
implicit operatorbruges til konverteringer, der altid er sikre og ikke mister data.explicit operatorbruges, når data kan gå tabt, eller konverteringen kan mislykkes.- Konverteringer kan gå til indbyggede eller brugerdefinerede typer i begge retninger.
- De er
public staticog erklæres af en af de involverede typer.
Lær C# med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 93
- Lektioner
- 346
Ofte stillede spørgsmål
Er lektionen “Brugerdefinerede konverteringer” gratis?
Ja — hele teksten til “Brugerdefinerede konverteringer” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af C# Academy-kurset, skal du opgradere til CoddyKit PRO. C# Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Brugerdefinerede konverteringer”?
Tilføj implicitte og eksplicitte konverteringsoperatorer. Du øver dig i C# Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på C# Academy?
Der kræves ingen tidligere erfaring. C# Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.
Hvor lang tid tager lektionen “Brugerdefinerede konverteringer”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne C# Academy-lektion?
Ja. Alle C# Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Overload af aritmetiske operatorer
- Overload af sammenligningsoperatorer
- Brugerdefinerede konverteringer
- Best practices for operator-overload