الأنواع المخصّصة الداعمة للنطاقات
أضيفوا دعم Index وRange إلى أنواعكم
الأنواع المخصّصة الداعمة للنطاقات درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 4 دروس في المجموع.
طريقتان لدعم الفهارس والنطاقات
يمكن لأنواعكم الخاصة اختيار دعم صياغة 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)المواضع المحسوبة من النهاية.
تعلم C# مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 93
- الدروس
- 346
الأسئلة الشائعة
هل درس «الأنواع المخصّصة الداعمة للنطاقات» مجاني؟
نعم — نص درس «الأنواع المخصّصة الداعمة للنطاقات» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 4 دروس في المجموع.
ماذا ستتعلم في «الأنواع المخصّصة الداعمة للنطاقات»؟
أضيفوا دعم Index وRange إلى أنواعكم تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟
لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «الأنواع المخصّصة الداعمة للنطاقات»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟
نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- النوع Index والعامل ^
- النوع Range والعامل ..
- النطاقات مع المصفوفات والسلاسل النصية
- الأنواع المخصّصة الداعمة للنطاقات