การกำหนดเมธอดส่วนขยาย
เขียนเมธอดแบบสแตติกด้วยตัวปรับแต่ง this
การกำหนดเมธอดส่วนขยาย เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
เมธอดส่วนขยายคืออะไร
เมธอดส่วนขยายช่วยให้คุณเพิ่มเมธอดใหม่ให้กับชนิดที่มีอยู่แล้วได้โดยไม่ต้องแก้ไขชนิดนั้นหรือสร้างชนิดที่สืบทอด คุณเรียกใช้เมธอดนี้เสมือนเป็นเมธอดของอินสแตนซ์ แต่จริง ๆ แล้วเป็นเมธอด static แบบพิเศษ
ส่วนขยายเหมาะอย่างยิ่งเมื่อคุณไม่ได้เป็นเจ้าของซอร์สโค้ดของชนิดนั้น (เช่น string หรือ int) แต่ต้องการเพิ่มพฤติกรรมใหม่ที่เรียกใช้ได้สะดวก
ข้อกำหนดสามประการ
การประกาศเมธอดส่วนขยายต้องมีสิ่งต่อไปนี้: คลาส static, เมธอด static และพารามิเตอร์ตัวแรกที่ระบุคำสำคัญ this พารามิเตอร์ this จะระบุชนิดที่คุณกำลังขยาย
using System;
public static class StringExtensions
{
public static int WordCount(this string text)
{
if (string.IsNullOrWhiteSpace(text)) return 0;
return text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Length;
}
}
public class Program
{
public static void Main()
{
string sentence = "the quick brown fox";
Console.WriteLine(sentence.WordCount());
}
}เรียกใช้เสมือนเมธอดของอินสแตนซ์
แม้ว่า WordCount จะเป็น static แต่คุณเรียกใช้เป็น sentence.WordCount() คอมไพเลอร์จะแปลงการเรียกนี้เบื้องหลังให้เป็น StringExtensions.WordCount(sentence)
using System;
using System.Linq;
public static class StringExtensions
{
public static string Repeat(this string text, int times)
{
return string.Concat(Enumerable.Repeat(text, times));
}
}
public class Program
{
public static void Main()
{
// These two lines do exactly the same thing
Console.WriteLine("ab".Repeat(3));
Console.WriteLine(StringExtensions.Repeat("ab", 3));
}
}พารามิเตอร์ this รับอินสแตนซ์
ค่าที่อยู่ทางซ้ายของจุดจะกลายเป็นพารามิเตอร์ this คุณสามารถเพิ่มพารามิเตอร์อื่นต่อจากนั้นได้ และผู้เรียกจะส่งค่าให้พารามิเตอร์เหล่านั้นตามปกติ
using System;
public static class IntExtensions
{
public static bool IsBetween(this int value, int low, int high)
{
return value >= low && value <= high;
}
}
public class Program
{
public static void Main()
{
int age = 25;
Console.WriteLine(age.IsBetween(18, 65));
Console.WriteLine(10.IsBetween(1, 5));
}
}การขยายชนิดของคุณเอง
ส่วนขยายไม่ได้มีไว้สำหรับชนิดจากไลบรารีเท่านั้น คุณสามารถขยายคลาสของคุณเองได้เช่นกัน ซึ่งมีประโยชน์ในการรักษาชนิดหลักให้กระชับ ขณะเดียวกันก็เพิ่มพฤติกรรมช่วยเหลือไว้ในที่อื่น
using System;
public class Money
{
public decimal Amount { get; }
public Money(decimal amount) { Amount = amount; }
}
public static class MoneyExtensions
{
public static string ToUsd(this Money m) => "$" + m.Amount.ToString("0.00");
}
public class Program
{
public static void Main()
{
var price = new Money(19.5m);
Console.WriteLine(price.ToUsd());
}
}ส่วนขยายเข้าถึงสมาชิกส่วนตัวไม่ได้
เมธอดส่วนขยายเป็นเพียงเมธอด static ในคลาสอื่น ดังนั้นจึงใช้ได้เฉพาะส่วนที่เปิดเผยต่อสาธารณะ (หรือส่วนภายในเมื่ออยู่ในชุดรวมโปรแกรมเดียวกัน) ของชนิดนั้น ไม่สามารถเข้าถึงเขตข้อมูลส่วนตัวได้
using System;
public class Counter
{
private int _count;
public int Value => _count;
public void Increment() => _count++;
}
public static class CounterExtensions
{
// Can only use public members like Value and Increment
public static bool IsZero(this Counter c) => c.Value == 0;
}
public class Program
{
public static void Main()
{
var c = new Counter();
Console.WriteLine(c.IsZero());
c.Increment();
Console.WriteLine(c.IsZero());
}
}การเชื่อมเมธอดส่วนขยายต่อกัน
เนื่องจากส่วนขยายแต่ละรายการคืนค่า คุณจึงสามารถเชื่อมต่อส่วนขยายเหล่านั้นเป็นลำดับการประมวลผลแบบต่อเนื่องได้ รูปแบบนี้อ่านจากบนลงล่าง และเป็นรูปแบบที่ LINQ ใช้
using System;
public static class TextExtensions
{
public static string Shout(this string s) => s.ToUpper();
public static string Bang(this string s) => s + "!";
}
public class Program
{
public static void Main()
{
string result = "hello".Shout().Bang();
Console.WriteLine(result);
}
}ค่าว่างและเมธอดส่วนขยาย
ต่างจากการเรียกเมธอดของอินสแตนซ์จริง เมธอดส่วนขยายยังทำงานได้แม้ตัวรับจะเป็น null เพราะจะยังไม่มีการเข้าถึงผ่านการอ้างอิงจนกว่าโค้ดของคุณจะไปแตะค่าดังกล่าว วิธีนี้ช่วยให้เขียนตัวช่วยที่ปลอดภัยต่อค่าว่างได้
using System;
public static class StringExtensions
{
public static bool IsBlank(this string text)
{
// text may be null here, and that is fine
return string.IsNullOrWhiteSpace(text);
}
}
public class Program
{
public static void Main()
{
string nothing = null;
Console.WriteLine(nothing.IsBlank());
Console.WriteLine("x".IsBlank());
}
}เมธอดของอินสแตนซ์มีสิทธิ์เหนือส่วนขยาย
หากมีเมธอดของอินสแตนซ์จริงที่มีลายเซ็นตรงกัน คอมไพเลอร์จะเลือกเมธอดนั้นก่อนเมธอดส่วนขยายเสมอ ส่วนขยายจึงมีไว้เติมความสามารถที่ชนิดนั้นยังไม่มีเท่านั้น
using System;
public static class Ext
{
// This will be ignored because string already has ToString()
public static string ToString(this string s, int n) => s + n;
}
public class Program
{
public static void Main()
{
// Resolves to the built-in instance ToString(), not the extension
Console.WriteLine("value: " + "abc".ToString());
}
}ไลบรารีตัวช่วยที่ใช้งานได้จริง
การรวมส่วนขยายที่เกี่ยวข้องไว้ในคลาส static เดียวกันจะสร้างไลบรารียูทิลิตีที่เป็นระเบียบ นี่คือตัวอย่างคลาสตัวช่วยด้านตัวเลขขนาดเล็กที่คุณอาจนำกลับมาใช้ในโครงการต่าง ๆ
using System;
public static class NumberExtensions
{
public static bool IsEven(this int n) => n % 2 == 0;
public static int Squared(this int n) => n * n;
public static double Percent(this int n) => n / 100.0;
}
public class Program
{
public static void Main()
{
Console.WriteLine(4.IsEven());
Console.WriteLine(5.Squared());
Console.WriteLine(50.Percent());
}
}ลองทำด้วยตนเอง
นำสิ่งที่เรียนรู้มาผสานกัน: สร้างคลาส static หนึ่งคลาสที่มีส่วนขยายหลายรายการ โดยเรียกใช้ต่อเนื่องอย่างเป็นธรรมชาติ นี่คือวิธีสร้างไลบรารีตัวช่วยที่ใช้ในชีวิตประจำวัน
using System;
public static class StringExtensions
{
public static string Capitalize(this string s)
=> string.IsNullOrEmpty(s) ? s : char.ToUpper(s[0]) + s.Substring(1);
public static string Surround(this string s, char c) => c + s + c;
}
public class Program
{
public static void Main()
{
Console.WriteLine("hello".Capitalize().Surround('*'));
}
}ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจของคุณเกี่ยวกับการประกาศเมธอดส่วนขยาย
ทบทวน
คุณได้เรียนรู้ว่า เมธอดส่วนขยายคือเมธอด static ในคลาส static ซึ่งพารามิเตอร์ตัวแรกใช้ this เมธอดนี้เรียกใช้ด้วยรูปแบบของอินสแตนซ์ แต่เมื่อคอมไพล์แล้วจะกลายเป็นการเรียก static ตามปกติ
- ข้อกำหนดสามประการ: คลาส static เมธอด static และพารามิเตอร์ตัวแรกเป็น
this - เข้าถึงได้เฉพาะสมาชิกสาธารณะ
- เมธอดของอินสแตนซ์มีสิทธิ์ก่อนเสมอ
- ส่วนขยายสามารถเชื่อมต่อกันได้ และยังทำงานกับตัวรับที่เป็น
nullได้
คำถามที่พบบ่อย
บทเรียน “การกำหนดเมธอดส่วนขยาย” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การกำหนดเมธอดส่วนขยาย” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การกำหนดเมธอดส่วนขยาย”
เขียนเมธอดแบบสแตติกด้วยตัวปรับแต่ง this คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “การกำหนดเมธอดส่วนขยาย” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การกำหนดเมธอดส่วนขยาย
- การขยายอินเทอร์เฟซและชนิดทั่วไป
- การค้นหาเมธอดส่วนขยาย
- การออกแบบส่วนขยายที่ดี