Käyttäjän määrittämät muunnokset
Lisätkää implisiittiset ja eksplisiittiset muunnosoperaattorit.
Käyttäjän määrittämät muunnokset on ilmainen C# Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu C# Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C# Academy-kurssilla on yhteensä 4 oppituntia.
Käyttäjän määrittämät muunnokset
C#:ssa tyyppi voi määritellä, miten se muunnetaan toiseksi tyypiksi tai miten toinen tyyppi muunnetaan siksi käyttämällä implicit- ja explicit-operaattoreita. Implisiittiset muunnokset tapahtuvat automaattisesti, kun taas eksplisiittiset muunnokset edellyttävät tyyppimuunnosta.
Implisiittinen muunnos
Käyttäkää implicit operator-operaattoria, kun muunnos on aina turvallinen eikä hävitä tietoa. Kääntäjä soveltaa sitä automaattisesti kaikkialla, missä kohdetyyppiä odotetaan.
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);
}
}Eksplisiittinen muunnos
Käyttäkää explicit operator-operaattoria, kun muunnos voi hävittää tietoa tai epäonnistua. Kutsujan on kirjoitettava tyyppimuunnos, mikä ilmaisee riskin hyväksymisen.
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);
}
}Muuntaminen omaksi tyypiksi
Muunnos voi tapahtua myös toiseen suuntaan: toisesta tyypistä omaksi tyypiksenne. Tässä implicit-operaattori muodostaa Celsius-arvon raakaluvusta 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);
}
}Implisiittinen vai eksplisiittinen: valinta
Nyrkkisääntö on seuraava: käytä implisiittistä muunnosta vain, jos tietoa ei koskaan häviä eikä muunnos koskaan aiheuta poikkeusta. Jos tarkkuutta voi hävitä, arvo voi ylivuotaa tai muunnos voi epäonnistua, tee siitä eksplisiittinen.
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);
}
}Muunnokset omien tyyppien välillä
Muunnokset eivät rajoitu sisäänrakennettuihin tyyppeihin. Voit muuntaa kaksi omaa tyyppiä keskenään, esimerkiksi napakoordinaatit suorakulmaisiksi koordinaateiksi.
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);
}
}Muunnokset toimivat yhdessä operaattorien kanssa
Kun muunnos on määritelty, arvo osallistuu kohdetyypin lausekkeisiin. Implisiittisen double-muunnoksen ansiosta tyyppiä voi käyttää suoraan aritmeettisissa laskuissa.
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);
}
}Vältä yllättäviä implisiittisiä muunnoksia
Implisiittiset muunnokset, jotka eivät ole ilmeisen turvallisia, voivat peittää virheitä, koska kääntäjä tekee ne kaikessa hiljaisuudessa. Jos olet epävarma, suosi eksplisiittistä muunnosta, jotta tarkoitus näkyy koodissa.
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);
}
}Muunnosoperaattorit ovat static
Muiden operaattorien tavoin muunnosoperaattorit ovat public static. Tasaan yhden mukana olevista tyypeistä on oltava operaattorin määrittelevä tyyppi.
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);
}
}Käytännöllinen wrapper-tyyppi
Muunnoksista on eniten hyötyä ohuille wrapper-tyypeille, jotka vahvistavat tyyppijärjestelmää ilman ylimääräistä vaivaa. Tässä NonEmptyString muunnetaan implisiittisesti tyypiksi string, mutta sen luominen edellyttää eksplisiittistä castia.
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);
}
}Kokeile itse
Määrittele wrapper, jolla on implisiittinen turvallinen muunnos ulospäin ja eksplisiittinen validoitu muunnos sisäänpäin. Huomaa, kumpi suunta edellyttää castia.
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 + "%");
}
}Pikatarkistus
Valitse oikea muunnostyyppi.
Kertaus
Käyttäjän määrittämät muunnokset mahdollistavat tyyppien sujuvan yhteistoiminnan.
implicit operatoraina turvallisiin ja häviöttömiin muunnoksiin.explicit operator, kun tietoa voi hävitä tai muunnos voi epäonnistua.- Muunnokset voivat kohdistua sisäänrakennettuihin tai omiin tyyppeihin kumpaankin suuntaan.
- Ne ovat
public staticja yhden mukana olevan tyypin määrittelemiä.
Opi C# tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 93
- Oppitunnit
- 346
Usein kysytyt kysymykset
Onko oppitunti ”Käyttäjän määrittämät muunnokset” ilmainen?
Kyllä – oppitunnin ”Käyttäjän määrittämät muunnokset” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko C# Academy-kurssin, päivitä CoddyKit PROhon. C# Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Käyttäjän määrittämät muunnokset”?
Lisätkää implisiittiset ja eksplisiittiset muunnosoperaattorit. Harjoittelet C# Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni C# Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin C# Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.
Kuinka kauan ”Käyttäjän määrittämät muunnokset”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä C# Academy-oppitunnilla?
Kyllä. Jokainen C# Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Aritmeettisten operaattorien ylikuormitus
- Vertailuoperaattorien ylikuormitus
- Käyttäjän määrittämät muunnokset
- Operaattorien ylikuormituksen parhaat käytännöt