0Pricing
C# Academy · บทเรียน

การแปลงที่ผู้ใช้กำหนด

เพิ่มตัวดำเนินการแปลงโดยนัยและโดยชัดแจ้ง

การแปลงที่ผู้ใช้กำหนด เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การโอเวอร์โหลดตัวดำเนินการเลขคณิต
  2. การโอเวอร์โหลดตัวดำเนินการเปรียบเทียบ
  3. การแปลงที่ผู้ใช้กำหนด
  4. แนวทางปฏิบัติที่ดีในการโอเวอร์โหลดตัวดำเนินการ
← กลับไปที่ C# Academy