Brukerdefinerte konverteringer
Legg til implisitte og eksplisitte konverteringsoperatorer.
Brukerdefinerte konverteringer er en gratis leksjon i C# Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i C# Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i C# Academy inneholder totalt 4 leksjoner.
Brukerdefinerte konverteringer
C# lar en type definere hvordan den konverteres til eller fra en annen type ved hjelp av operatorene implicit og explicit. Implisitte konverteringer skjer automatisk; eksplisitte konverteringer krever en cast.
En implicit-konvertering
Bruk implicit operator når en konvertering alltid er trygg og tapsfri. Kompilatoren bruker den automatisk overalt der 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 explicit-konvertering
Bruk explicit operator når en konvertering kan føre til tap av informasjon eller mislykkes. Kallere må skrive en cast, som signaliserer at de aksepterer 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);
}
}Konvertere til din type
Konverteringer kan også gå den andre veien: fra en annen type til din type. Her bygger en implicit-operator en Celsius 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);
}
}Implisitt eller eksplisitt: Valg
Tommelfingerregelen er: Gjør konverteringen implisitt bare hvis den aldri mister data og aldri gir feil. Hvis den kan miste presisjon, gi overflow eller mislykkes, bør den være eksplisitt.
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 mellom egendefinerte typer
Konverteringer er ikke begrenset til innebygde typer. De kan også brukes mellom to av dine egne typer, for eksempel fra polare 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 kan brukes med operatorer
Når en konvertering finnes, kan verdien brukes i uttrykk for måltypen. En implisitt konvertering til double gjør at typen din kan brukes direkte i aritmetikk.
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);
}
}Unngå overraskende implisitte konverteringer
Implisitte konverteringer som ikke åpenbart er trygge, kan skjule feil fordi kompilatoren bruker dem uten å si fra. Når du er i tvil, bør du foretrekke eksplisitte konverteringer slik at hensikten 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
I likhet med andre operatorer er konverteringsoperatorer public static. Nøyaktig én av de involverte typene må være typen som deklarerer 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 spesielt nyttige for tynne wrapper-typer som styrker typesystemet uten å skape unødvendig friksjon. Her konverteres en NonEmptyString implisitt til string, men det kreves en eksplisitt cast for å opprette 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
Definer en wrapper med en implisitt konvertering ut (trygg) og en eksplisitt konvertering inn (validert). Legg merke til hvilken retning som krever en cast.
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 + "%");
}
}Hurtigsjekk
Velg riktig type konvertering.
Oppsummering
Brukerdefinerte konverteringer gjør at typene dine kan samhandle på en ryddig måte.
implicit operatorfor konverteringer som alltid er trygge og ikke mister data.explicit operatornår data kan gå tapt eller konverteringen kan mislykkes.- Konverteringer kan gå til innebygde eller egendefinerte typer, i begge retninger.
- De er
public staticog deklareres av én av de involverte typene.
Lær deg C# med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 93
- Leksjoner
- 346
Ofte stilte spørsmål
Er leksjonen «Brukerdefinerte konverteringer» gratis?
Ja – hele teksten i «Brukerdefinerte konverteringer» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av C# Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i C# Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Brukerdefinerte konverteringer»?
Legg til implisitte og eksplisitte konverteringsoperatorer. Du øver på C# Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med C# Academy?
Ingen tidligere erfaring er nødvendig. C# Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.
Hvor lang tid tar leksjonen «Brukerdefinerte konverteringer»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne C# Academy-leksjonen?
Ja. Alle C# Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Overbelaste aritmetiske operatorer
- Overbelaste sammenligningsoperatorer
- Brukerdefinerte konverteringer
- Beste praksis for operatoroverbelastning