การแปลงที่ผู้ใช้กำหนด
เพิ่มตัวดำเนินการแปลงโดยนัยและโดยชัดแจ้ง
การแปลงที่ผู้ใช้กำหนด เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
การแปลงชนิดข้อมูลที่ผู้ใช้กำหนด
C# อนุญาตให้ชนิดข้อมูลกำหนดวิธีแปลงไปเป็นหรือแปลงกลับจากชนิดข้อมูลอื่นโดยใช้ตัวดำเนินการ implicit และ explicit การแปลงโดยนัยเกิดขึ้นโดยอัตโนมัติ ส่วนการแปลงโดยชัดแจ้งต้องใช้การแปลงชนิด
การแปลงโดยนัย
ใช้ implicit operator เมื่อการแปลงปลอดภัยและไม่สูญเสียข้อมูลเสมอ คอมไพเลอร์จะนำไปใช้โดยอัตโนมัติทุกแห่งที่คาดว่าจะเป็นชนิดข้อมูลปลายทาง
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);
}
}การแปลงโดยชัดแจ้ง
ใช้ explicit operator เมื่อการแปลงอาจทำให้ข้อมูลสูญหายหรือล้มเหลว ผู้เรียกต้องเขียนการแปลงชนิดเพื่อแสดงว่ายอมรับความเสี่ยงดังกล่าว
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);
}
}การแปลงเป็นชนิดข้อมูลของคุณ
การแปลงสามารถทำได้ในทิศทางกลับกันด้วย นั่นคือจากชนิดข้อมูลอื่นมาเป็นชนิดข้อมูลของคุณ ในที่นี้ตัวดำเนินการ implicit จะสร้าง Celsius จากค่า 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);
}
}การเลือกระหว่างแบบโดยนัยกับแบบชัดแจ้ง
หลักง่าย ๆ คือ ให้ใช้การแปลงแบบ โดยนัย เฉพาะเมื่อไม่มีทางสูญเสียข้อมูลและไม่ทำให้เกิดข้อผิดพลาด หากอาจสูญเสียความละเอียด เกิดค่าล้น หรือทำงานล้มเหลว ให้ใช้การแปลงแบบ ชัดแจ้ง
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);
}
}การแปลงระหว่างชนิดข้อมูลที่กำหนดเอง
การแปลงไม่ได้จำกัดอยู่แค่ชนิดข้อมูลในตัวเท่านั้น คุณสามารถแปลงระหว่างชนิดข้อมูลที่กำหนดเองสองชนิดได้ เช่น แปลงจากพิกัดเชิงขั้วเป็นพิกัดคาร์ทีเซียน
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);
}
}การแปลงทำงานร่วมกับตัวดำเนินการ
เมื่อมีการแปลงแล้ว ค่าใด ๆ จะเข้าร่วมในนิพจน์ของชนิดข้อมูลปลายทางได้ การแปลงแบบโดยนัยเป็น double ทำให้สามารถนำชนิดข้อมูลของคุณไปใช้คำนวณทางคณิตศาสตร์ได้โดยตรง
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);
}
}หลีกเลี่ยงการแปลงแบบโดยนัยที่สร้างความประหลาดใจ
การแปลงแบบโดยนัยที่ไม่ปลอดภัยอย่างเห็นได้ชัดอาจซ่อนข้อผิดพลาดไว้ได้ เพราะตัวแปลโปรแกรมนำการแปลงไปใช้โดยไม่มีการแจ้งเตือน หากไม่แน่ใจ ให้เลือกใช้การแปลงแบบชัดแจ้งเพื่อให้เจตนาปรากฏในโค้ด
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);
}
}ตัวดำเนินการแปลงเป็นแบบคงที่
เช่นเดียวกับตัวดำเนินการอื่น ๆ ตัวดำเนินการแปลงจะเป็น public static ชนิดข้อมูลที่เกี่ยวข้องหนึ่งชนิดพอดีต้องเป็นชนิดข้อมูลที่ประกาศตัวดำเนินการนั้น
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);
}
}ชนิดข้อมูลห่อหุ้มที่ใช้งานได้จริง
การแปลงมีประโยชน์อย่างมากกับชนิดข้อมูลห่อหุ้มแบบบางที่ช่วยเสริมระบบชนิดข้อมูลโดยไม่ทำให้ใช้งานยุ่งยาก ในที่นี้ NonEmptyString จะแปลงเป็น string แบบโดยนัย แต่การสร้างค่านั้นต้องใช้การแคสต์แบบชัดแจ้ง
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);
}
}ลองทำด้วยตนเอง
กำหนดชนิดข้อมูลห่อหุ้มที่มีการแปลงขาออกแบบโดยนัย (ปลอดภัย) และการแปลงขาเข้าแบบชัดแจ้ง (ผ่านการตรวจสอบ) สังเกตว่าทิศทางใดต้องใช้การแคสต์
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 + "%");
}
}ตรวจสอบอย่างรวดเร็ว
เลือกชนิดการแปลงที่เหมาะสม
สรุปทบทวน
การแปลงที่ผู้ใช้กำหนดช่วยให้ชนิดข้อมูลของคุณทำงานร่วมกันได้อย่างราบรื่น
implicit operatorสำหรับการแปลงที่ปลอดภัยเสมอและไม่สูญเสียข้อมูลexplicit operatorเมื่อข้อมูลอาจสูญหายหรือการแปลงอาจล้มเหลว- การแปลงสามารถมุ่งไปยังชนิดข้อมูลในตัวหรือชนิดข้อมูลที่กำหนดเองได้ทั้งสองทิศทาง
- การแปลงเหล่านี้เป็น
public staticและประกาศโดยชนิดข้อมูลใดชนิดหนึ่งที่เกี่ยวข้อง
คำถามที่พบบ่อย
บทเรียน “การแปลงที่ผู้ใช้กำหนด” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การแปลงที่ผู้ใช้กำหนด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การแปลงที่ผู้ใช้กำหนด”
เพิ่มตัวดำเนินการแปลงโดยนัยและโดยชัดแจ้ง คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การแปลงที่ผู้ใช้กำหนด” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การโอเวอร์โหลดตัวดำเนินการเลขคณิต
- การโอเวอร์โหลดตัวดำเนินการเปรียบเทียบ
- การแปลงที่ผู้ใช้กำหนด
- แนวทางปฏิบัติที่ดีในการโอเวอร์โหลดตัวดำเนินการ