ชนิดข้อมูลแบบกำหนดเองที่รองรับช่วง
เพิ่มการรองรับ Index และ Range ให้ชนิดข้อมูลของคุณ
ชนิดข้อมูลแบบกำหนดเองที่รองรับช่วง เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
สองวิธีในการรองรับ Index และ Range
ชนิดข้อมูลที่คุณสร้างเองสามารถเลือกรองรับไวยากรณ์ของ Index และ Range ได้ มีสองแนวทาง ได้แก่ จัดเตรียมตัวเข้าถึงดัชนีอย่างชัดเจน หรือจัดเตรียมคุณสมบัติ Length/Count พร้อมเมธอด Slice
ตัวเข้าถึงดัชนี Index อย่างชัดเจน
เพิ่มตัวเข้าถึงดัชนีที่รับ System.Index แล้วตัวดำเนินการ ^ ก็จะทำงานกับชนิดข้อมูลของคุณได้ทันที
using System;
class Deck {
private int[] cards = { 1, 2, 3, 4, 5 };
public int this[Index i] => cards[i];
}
var d = new Deck();
Console.WriteLine(d[^1]); // 5ตัวเข้าถึงดัชนี Range อย่างชัดเจน
หากต้องการรองรับการตัดแบ่งด้วย .. ให้เพิ่มตัวเข้าถึงดัชนีที่รับ System.Range และคืนค่าชนิดส่วนย่อยที่คุณต้องการ
using System;
class Deck {
private int[] cards = { 1, 2, 3, 4, 5 };
public int[] this[Range r] => cards[r];
}
var d = new Deck();
Console.WriteLine(string.Join(",", d[1..3])); // 2,3รูปแบบ Length + Slice
คอมไพเลอร์ยังสามารถสร้างการรองรับช่วงให้โดยอัตโนมัติ หากชนิดข้อมูลของคุณมีคุณสมบัติ Count หรือ Length และมีเมธอด Slice(int start, int length)
การนำรูปแบบไปใช้งาน
ในตัวอย่างนี้ บัฟเฟอร์ที่กำหนดเองเปิดเผย Length และ Slice คอมไพเลอร์จะแปลง buf[1..3] เป็น buf.Slice(1, 2) ให้คุณโดยอัตโนมัติ
using System;
class Buffer {
private int[] data = { 10, 20, 30, 40 };
public int Length => data.Length;
public int this[int i] => data[i];
public int[] Slice(int start, int length) {
var result = new int[length];
Array.Copy(data, start, result, 0, length);
return result;
}
}
var buf = new Buffer();
Console.WriteLine(string.Join(",", buf[1..3])); // 20,30เหตุใด Length จึงสำคัญ
คุณสมบัติ Length (หรือ Count) ช่วยให้คอมไพเลอร์แปลงดัชนีจากท้าย เช่น ^1 สำหรับชนิดข้อมูลของคุณได้ หากไม่มีคุณสมบัตินี้ ก็ไม่สามารถแปลง ^ ได้
using System;
class Buffer {
private int[] data = { 10, 20, 30, 40 };
public int Length => data.Length;
public int this[Index i] => data[i.GetOffset(Length)];
}
var buf = new Buffer();
Console.WriteLine(buf[^1]); // 40การแปลง Index ด้วยตนเอง
ภายในตัวเข้าถึงดัชนีของ Index ให้เรียก i.GetOffset(Length) เพื่อแปลงดัชนีที่อาจนับจากท้ายให้เป็นออฟเซ็ตทั่วไป
using System;
class Ring {
private string[] items = { "a", "b", "c" };
public int Length => items.Length;
public string this[Index i] {
get {
int offset = i.GetOffset(Length);
return items[offset];
}
}
}
var r = new Ring();
Console.WriteLine(r[^2]); // bการแปลง Range ด้วยตนเอง
สำหรับตัวเข้าถึงดัชนีของ Range เมธอด r.GetOffsetAndLength(Length) จะให้ทั้งตำแหน่งเริ่มต้นและจำนวนสมาชิกที่จะคัดลอก
using System;
class Ring {
private int[] items = { 1, 2, 3, 4, 5 };
public int Length => items.Length;
public int[] this[Range r] {
get {
var (start, len) = r.GetOffsetAndLength(Length);
var slice = new int[len];
Array.Copy(items, start, slice, 0, len);
return slice;
}
}
}
var r = new Ring();
Console.WriteLine(string.Join(",", r[^3..^1])); // 3,4Count เทียบกับ Length
รูปแบบนี้ยอมรับชื่อใดชื่อหนึ่งก็ได้ อาร์เรย์และช่วงหน่วยความจำใช้ Length ส่วน List<T> ใช้ Count คุณสมบัติอย่างใดอย่างหนึ่งก็เพียงพอสำหรับคอมไพเลอร์
using System;
using System.Collections.Generic;
var list = new List<int> { 1, 2, 3, 4 };
// List<T> has Count, so Index works:
Console.WriteLine(list[^1]); // 4การออกแบบชนิดค่าที่คืนจาก Slice
ตัดสินใจว่า Slice จะคืนค่าสำเนา (เช่นเดียวกับอาร์เรย์) หรือมุมมอง (เช่นเดียวกับช่วงหน่วยความจำ) มุมมองใช้ทรัพยากรน้อยกว่า แต่ใช้สถานะที่เปลี่ยนแปลงร่วมกัน ดังนั้นควรระบุการเลือกนี้ไว้ในเอกสาร
ชนิดข้อมูลกำหนดเองที่สมบูรณ์
Sequence นี้รองรับทั้ง ^ และ .. ผ่านตัวเข้าถึงดัชนีที่ระบุอย่างชัดเจนและคุณสมบัติ Length
using System;
class Sequence {
private int[] data;
public Sequence(int[] d) => data = d;
public int Length => data.Length;
public int this[Index i] => data[i];
public int[] this[Range r] => data[r];
}
var s = new Sequence(new[] { 5, 10, 15, 20 });
Console.WriteLine(s[^1]); // 20
Console.WriteLine(string.Join(",", s[1..^1])); // 10,15ตรวจสอบความเข้าใจอย่างรวดเร็ว
ยืนยันว่าคุณเข้าใจสิ่งที่ทำให้ไวยากรณ์ช่วงใช้งานได้กับชนิดข้อมูลกำหนดเอง
สรุปทบทวน
คุณได้เรียนรู้สองวิธีในการเพิ่มการรองรับ Index/Range ให้กับชนิดข้อมูลของคุณ
- ตัวเข้าถึงดัชนีที่ระบุอย่างชัดเจนและรับ
IndexกับRange - รูปแบบโดยนัย: คุณสมบัติ
Count/Lengthพร้อมSlice(int, int) GetOffset(Length)และGetOffsetAndLength(Length)ใช้แปลงตำแหน่งจากท้าย
คำถามที่พบบ่อย
บทเรียน “ชนิดข้อมูลแบบกำหนดเองที่รองรับช่วง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ชนิดข้อมูลแบบกำหนดเองที่รองรับช่วง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ชนิดข้อมูลแบบกำหนดเองที่รองรับช่วง”
เพิ่มการรองรับ Index และ Range ให้ชนิดข้อมูลของคุณ คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “ชนิดข้อมูลแบบกำหนดเองที่รองรับช่วง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ชนิด Index และตัวดำเนินการ ^
- ชนิด Range และตัวดำเนินการ ..
- ช่วงกับอาร์เรย์และสตริง
- ชนิดข้อมูลแบบกำหนดเองที่รองรับช่วง