محتويات الدورة

C# / الأساسي: البرامج ذات الأنواع وعقود الكائنات / الدرس 4

المجموعات والنصوص والحدود

افصل طول المتتالية وهوية التخزين ووجود المفتاح ووحدات النص قبل اختيار العمليات.

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • اختيار المصفوفات والقوائم والقواميس بالعقد.
  • شرح المشاركة والنسخ السطحي.
  • تمييز وحدات UTF-16 من قيم Unicode القياسية.

اختيار نمط الوصول أولا

للمصفوفة طول ثابت وتدير List<T> متتالية متغيرة بـCount وCapacity ويوفر Dictionary بحثا بمفتاح. Count عدد منطقي والسعة تخزين لا يبيح فهرسة خارجه. استخدم مجالا نصف مفتوح وعالج الفراغ قبل افتراض العنصر صفر. لا تسمح زيادة Capacity بقراءة عنصر لم يدخل Count، وتظل حالة المجموعة الفارغة مسارا يجب اختباره.

اختر المجموعة من العمليات والملكية. ينسخ إسناد القائمة مرجعا فيسمي متغيران القائمة نفسها. ينسخ الاستنساخ أوnew List<T>(source) قيم العناصر لا كل الأهداف تكراريا. وقد يظل الداخل قابلا للتعديل مشتركا رغم استقلال الخارج. يعني استقلال التخزين الخارجي إمكان استبدال خانة دون الأخرى، لكنه لا يمنع تعديل كائن مرجعي مشترك عبر الخانتين.

جعل نسخ المجموعة صريحا

ينشئ المثال اسما بديلا ونسخة عناصر مستقلة. يغير alias[0] الأصل ويغير copied[1] النسخة فقط لأن int بلا مراجع داخلية. يعرض الخرج الهوية والنسخ دون اعتماد على نمو السعة. لا يعتمد المثال على سياسة توسع List الداخلية، ولذلك تبقى النتيجة مفهومة حتى لو تغير التنفيذ.

في قائمة Person قابلة للتعديل تبقى النسخة مشيرة للأشخاص أنفسهم. حدد المنظور المستعار أواللقطة السطحية أوالاستقلال المتكرر. تقيد IReadOnlyList<T> عمليات الواجهة ولا تجمد الأصل ولا عناصره. عندما يطلب المستهلك لقطة ثابتة، يجب أن يضمن العقد حالة المصدر وقت النسخ وعمق استقلال العناصر معا.

csharp اسم بديل وقائمة أعداد مستقلة
using System;
using System.Collections.Generic;

var original = new List<int> { 1, 2, 3 };
var alias = original;
var copied = new List<int>(original);
alias[0] = 9;
copied[1] = 8;
Console.WriteLine(string.Join(",", original));
Console.WriteLine(string.Join(",", copied));
الناتج المتوقع
9,2,3
1,8,3

يغير الاسم البديل الأصل ولنسخة العناصر تخزين قائمة مستقل.

الوجود مختلف عن القيمة الافتراضية

تميز TryGetValue الغائب من عنصر موجود بقيمة default. يرمي البحث بالفهرس عند الغياب. اختر مقارنا مناسبا؛ تحتاج رموز البروتوكول غالبا Ordinal بينما للمطابقة اللغوية متطلبات أخرى. لا تترك الثقافة المحيطة تحدد هوية المعرف عرضا. من المفيد اختبار مفتاح موجود بقيمة صفر بجانب مفتاح غائب؛ يثبت ذلك أن التطبيق لا يستخدم القيمة الافتراضية كعلامة غياب.

إذا هم الترتيب فأثبته بفرز أوهيكل بعقد مناسب. لا تعتمد على ترتيب قاموس شوهد كضمان تسلسل عام. ويحتاج التعديل أثناء الاجتياز قواعد المجموعة وسياسة تزامن. تدخل قواعد المقارنة في معنى المعرف نفسه، ولذلك تكون مراجعتها جزءا من تنسيق البيانات لا مجرد اختيار أداء.

ترتيب العرض وفحص نجاح البحث

يخزن المثال صفرا صحيحا ويبحث الغائب منفصلا. يجعل الفرز apple قبل pear دون تفاصيل الإدراج. تخبر منطقية TryGetValue هل الصفر غياب أمسجل. ولا توجد كتابة متزامنة هنا. يمكن ترتيب العرض دون الادعاء بأن القاموس صار مرتبا؛ العمليات الأساسية والتمثيل الخارجي مسؤوليتان مختلفتان.

يجب أن تغطي لقطة الإنتاج الحالة بالمزامنة. نسخ المفاتيح مع تغير القيم ليس لقطة متسقة بالضرورة ولو لم ترم العمليات. افصل الترتيب والوجود واتساق اللقطة. إذا كتب خيط آخر أثناء النسخ، فلابد من قفل أو مصدر ثابت يبرر اللقطة كلها لا قراءة مفاتيح فقط.

csharp خرج مفاتيح ثابت مع الوجود
using System;
using System.Collections.Generic;
using System.Linq;

var counts = new Dictionary<string, int>(StringComparer.Ordinal)
{
    ["pear"] = 2, ["apple"] = 0
};
foreach (string key in counts.Keys.OrderBy(key => key, StringComparer.Ordinal))
{
    Console.WriteLine($"{key}={counts[key]}");
}
bool present = counts.TryGetValue("missing", out int value);
Console.WriteLine($"missing={present} value={value}");
الناتج المتوقع
apple=0
pear=2
missing=False value=0

يثبت الفرز الترتيب ويعيد البحث الغائب false وصفر int.

طول النص عدد وحدات UTF-16

نصوص.NET متتاليات UTF-16 ثابتة؛ تعد Length وفهرسة char وحداتها لا القيم القياسية أوالمحارف المدركة بالضرورة. تستخدم قيمة تكميلية زوج بدائل وقد تحوي وحدة مرئية عدة قيم. استخدم Rune أوواجهات العناصر النصية حسب المطلب. قد تتكون الصورة المرئية من عدة قيم Unicode، فلا يكفي عد الرونات أيضا لكل متطلب عرض بشري.

لا يمنح foreach عادة إذن تعديل بنيوي أثناء الاجتياز. تكشف مجتازات كثيرة الإبطال وترمي وتختلف السماحات حسب المجموعة. فضل تحديثا منفصلا أولقطة مقصودة. ولا يصنع ثبات النص بروتوكول تزامن كاملا لإسناد متغير مشترك. الاستثناء أثناء الاجتياز إشارة لخرق سياسة، ولا ينبغي تحويله إلى تجاهل صامت للعناصر المفقودة.

الأخطاء الشائعة وإصلاحها

يغير نسخ قائمة كائنات أخرى.

لماذا يحدث؟
نُسخت مراجع العناصر الخارجية فقط.
كيف تصلحه؟
استنسخ الداخل أووثق الاستعارة.
كيف تتجنب تكراره؟
اختبر المشاركة صراحة.

ينهار مسار عادي لمفتاح غائب.

لماذا يحدث؟
يفترض الفهرس الوجود.
كيف تصلحه؟
استخدم TryGetValue للغياب المتوقع.
كيف تتجنب تكراره؟
اختبر الصفر المخزن والغائب منفصلين.

يبتر النص محرف Unicode.

لماذا يحدث؟
اختلطت وحداتUTF-16 بالوحدة المطلوبة.
كيف تصلحه؟
استخدم معالجة قياسية أوعنقودية مناسبة.
كيف تتجنب تكراره؟
اختبر البدائل والتراكيب.

اختبر فهمك

1. هل تضمن IReadOnlyList<Person> ثبات القائمة والأشخاص؟

اعرض الحل المشروح

لا؛ تقيد الواجهة وقد يعدل اسم آخر الأصل ويبقى Person متغيرا. للّقطة المستقلة انسخ تحت المزامنة واختر عناصر ثابتة أوصيغة نسخ عميق. وثق هل الاجتياز حي أونتيجة ملتقطة.

2. صمم نتيجة حساب مجهول مع أرصدة منها صفر دون علامة عددية.

اعرض الحل المشروح

استخدم TryGetValue وأعد الوجود مع الرصيد أوحوله لنتيجة مجال موثقة. احفظ الصفر كبيانات واحم البحث مع التحديث في المشترك. اختبر الغائب والصفر والموجب والمقارن وحدد معنى حالة الأحرف.

أهم ما تعلمته

  • العدد المنطقي وهوية التخزين ووجود المفتاح مختلفة.
  • لا تنشئ القراءة فقط لقطة ثابتة تلقائيا.
  • ينبغي تسمية وحدة Unicode صراحة.

المراجع الرسمية