string في C# سلسلة من محارف UTF-16 (قيم char). هو نوع مرجعي، لكنه يتصرف كقيمة في الجوانب المهمة: غير قابل للتغيير، و== تقارن النص لا هوية الكائن. string هي الكلمة المحجوزة في C# لنوع .NET System.String؛ ويمكن استخدام أحدهما مكان الآخر.
المخرجات:
Porto
5
0
*****
hi
Porto has 5 letters
النصوص غير قابلة للتغيير
لا توجد دالة تغيّر نصًا في مكانه. تعيد ToUpper وReplace وTrim وكل دالة أخرى نصًا جديدًا وتترك الأصلي كما هو. نسيان استخدام القيمة المعادة خطأ شائع جدًا في النصوص:
المخرجات:
[ maya ]
[MAYA]
tea
tea and cake
عدم القابلية للتغيير يجعل النصوص آمنة للمشاركة بين الخيوط ولاستخدامها مفاتيح في القواميس. الثمن أن بناء نص قطعة قطعة في حلقة ينشئ نصًا جديدًا في كل خطوة؛ لذلك استخدم StringBuilder.
الطول والفهرسة
Length خاصية (بلا أقواس). يعيد المفهرس s[i] قيمة char في الموضع i، بدءًا من 0، وهو للقراءة فقط:
المخرجات:
7
A
1
IndexOutOfRangeException
XB-2931
تقبل C# 8 وما بعدها أيضًا فهرسًا من النهاية: code[^1] هو المحرف الأخير، مثل code[code.Length - 1]. لأخذ عدة محارف دفعة واحدة راجع substring.
تعدّ Length وحدات ترميز UTF-16، لا ما يراه القارئ محارف. معظم الأحرف في معظم اللغات وحدة واحدة، لكن الرموز التعبيرية وبعض الكتابات النادرة تستخدم وحدتين (زوجًا بديلًا)، فتكون "👍".Length مساوية لـ 2.
مقارنة النصوص
تقارن == و!= المحارف مع مراعاة حالة الأحرف. لأي شيء آخر مرّر قيمة StringComparison تحدد طريقة المقارنة:
المخرجات:
False
False
True
True
apple first
True
False
False
True
أي مقارنة تستخدم:
Ordinalتقارن الرموز الرقمية للمحارف. سريعة ومتوقعة ومتطابقة على كل جهاز. استخدمها للمعرّفات وأسماء الملفات والمفاتيح وقيم البروتوكولات وكل ما لا يُعرض على شخص.OrdinalIgnoreCaseمثلها مع تجاهل حالة الأحرف. الخيار الصحيح للفحوص غير الحساسة لحالة الأحرف مثل امتدادات الملفات أو ترويسات HTTP.CurrentCulture(وCurrentCultureIgnoreCase) تتبع قواعد لغة المستخدم، فترتّب الكلمات كما يرتّبها قاموس تلك اللغة. استخدمها لفرز القوائم المعروضة على المستخدمين.InvariantCultureتستخدم قواعد واعية بالثقافة لا تعتمد على إعدادات لغة المستخدم. لكنها ما زالت تعتمد على مكتبة العولمة: تستخدم .NET الحديثة ICU، وتستخدم .NET Framework مكتبة NLS في Windows، وقد يرتّب الاثنان بعض النصوص بشكل مختلف.
تستخدم string.Compare(a, b) وa.CompareTo(b) دون StringComparison الثقافة الحالية، وهذا يجعل نتائجهما تختلف بين الأجهزة. تجنّب المقارنة بـ a.ToLower() == b.ToLower(): فهي تحجز نصين جديدين، وتعطي إجابات خاطئة في بعض الثقافات (حرف i المنقوط وغير المنقوط في التركية هو الحالة التقليدية).
استدعاء a.Equals(b) حين تكون a هي null يرمي NullReferenceException، بينما تتعامل a == b والدالة الساكنة string.Equals(a, b) مع null بأمان.
محارف الهروب
داخل قيمة نصية حرفية عادية تبدأ الشرطة المائلة العكسية تسلسل هروب:
| الهروب | المعنى |
|---|---|
\n | سطر جديد (line feed) |
\r | إرجاع العربة |
\t | جدولة |
\\ | شرطة مائلة عكسية |
\" | علامة اقتباس مزدوجة |
\' | علامة اقتباس مفردة (لا تلزم إلا في قيمة char حرفية) |
\0 | المحرف الفارغ |
\uXXXX | محرف UTF-16 برمز ست عشري من 4 خانات، مثل \u00e9 |
\U0001F44D | محرف برمز ست عشري من 8 خانات؛ فوق U+FFFF يصبح قيمتي char |
\xH إلى \xHHHH | محرف بخانة إلى 4 خانات ست عشرية (تجنّبه: الطول ملتبس) |
\a، \b، \f، \v | تنبيه، مسح للخلف، تغذية صفحة، جدولة عمودية |
\e | محرف الهروب، U+001B (C# 13) |
المخرجات:
Name: Ana
City: Porto
She said "hi"
C:\temp\report.txt
cafe = cafe
' is a quote char
التسلسل غير المعروف مثل "\d" خطأ ترجمة (CS1009، unrecognized escape sequence)، وهذا ما يحدث حين يُكتب مسار Windows أو تعبير نمطي كنص عادي.
النصوص الحرفية verbatim والنصوص متعددة الأسطر
وضع @ قبل القيمة الحرفية يجعلها حرفية (verbatim): الشرطات المائلة العكسية محارف عادية، ويمكن للنص أن يمتد على عدة أسطر. الهروب الوحيد الباقي هو ""، الذي ينتج علامة اقتباس مزدوجة واحدة.
المخرجات:
C:\Users\ana\Documents\notes.txt
\d{3}-\d{4}
He said "ready" and left.
Rua das Flores 12
4050-262 Porto
Portugal
first line
second line
يتضمن النص الحرفي متعدد الأسطر كل ما بين علامتي الاقتباس، بما في ذلك إزاحة أسطر التكملة، ولهذا يُكتب عادة ملاصقًا للهامش كما في المثال أعلاه. وفواصل الأسطر التي يحتويها هي فواصل ملف المصدر نفسها، فالملف المحفوظ بنهايات أسطر Windows ينتج \r\n.
أضافت C# 11 النصوص الحرفية الخام (raw string literals)، التي تحل المشكلتين. تبدأ وتنتهي بثلاث علامات اقتباس مزدوجة أو أكثر، ولا تحتاج إلى أي هروب، وتزيل الإزاحة بمقدار إزاحة علامات الإغلاق:
// C# 11 and later
string json = """
{
"name": "Ana",
"path": "C:\temp"
}
""";
// The 4 spaces before the closing """ are removed from every line.
إن احتوى المحتوى نفسه على """ فابدأ وانتهِ بأربع علامات بدلًا من ذلك. تتّحد النصوص الخام مع الاستيفاء أيضًا ($"""...""")؛ راجع استيفاء النصوص.
null والفارغ والمسافات البيضاء
يمكن لمتغيّر نصي أن يكون null (لا نص إطلاقًا)، أو فارغًا (""، طوله 0)، أو لا يحتوي إلا على مسافات بيضاء. دالتان مساعدتان ساكنتان تفحصان هذه الحالات دون خطر NullReferenceException:
المخرجات:
null empty: True blank: True
"" empty: True blank: True
" " empty: False blank: True
"Ana" empty: False blank: False
True
للتحقق من مدخلات المستخدم تكون string.IsNullOrWhiteSpace في الغالب هي ما تريده. string.Empty و"" القيمة نفسها؛ وأيهما تكتب مسألة أسلوب.
المرور على المحارف
النص قابل للتعداد، فتزور foreach كل char. وللنوع char دوال ساكنة لتصنيف المحارف:
المخرجات:
letters=6 digits=4 upper=1 symbols=1
!6202tesnuS
ضمّ النصوص
تضمّ + النصوص، وتعمل مع أي نوع في الطرف الآخر (تستدعي ToString()). لدمج قيم كثيرة فضّل الاستيفاء أو string.Join:
المخرجات:
Ana Silva, 31
Ana Silva, 31
AnaSilva
tea | coffee | juice
Total: 23
Total: 5
يُظهر السطران الأخيران فخ أولوية: تُقيَّم + بترتيب ورودها، فبمجرد أن يصبح الطرف الأول نصًا يصبح كل + لاحق عملية ضمّ. ضع العمليات الحسابية بين أقواس داخل الضمّ.
الأسئلة الشائعة
كيف أحصل على طول نص في C#؟
استخدم الخاصية Length: "hello".Length تساوي 5. هي خاصية لا دالة، فلا أقواس. تعدّ Length وحدات ترميز UTF-16، فيُحسب الرمز التعبيري أو أي محرف آخر خارج المستوى متعدد اللغات الأساسي كاثنين. واستدعاؤها على نص null يرمي NullReferenceException.
كيف أقارن النصوص في C#؟
تقارن a == b النص وهي حساسة لحالة الأحرف. للمساواة غير الحساسة لحالة الأحرف استخدم string.Equals(a, b, StringComparison.OrdinalIgnoreCase). ولفرز النصوص أو ترتيبها استخدم string.Compare(a, b, StringComparison.Ordinal) أو مقارنة واعية بالثقافة، وهي تعيد رقمًا سالبًا أو صفرًا أو رقمًا موجبًا.
كيف أكتب نصًا متعدد الأسطر في C#؟
ضع البادئة @ قبل القيمة الحرفية لتجعلها حرفية (verbatim): يمكنها الامتداد على عدة أسطر، والشرطات المائلة العكسية حرفية، وتُكتب علامة الاقتباس المزدوجة "". في C# 11 وما بعده تمتد النصوص الحرفية الخام المحاطة بـ """ على عدة أسطر أيضًا، وتزيل الإزاحة المشتركة، ولا تحتاج إلى أي هروب. ويمكنك أيضًا وصل الأسطر بـ \n أو Environment.NewLine.
ما هو النص الحرفي verbatim في C#؟
قيمة نصية حرفية تسبقها @، مثل @"C:\Users\ana". لا تُعالج تسلسلات الهروب، فالشرطة المائلة العكسية مجرد شرطة مائلة عكسية، وهذا يجعله الخيار الطبيعي لمسارات Windows والتعابير النمطية. الهروب الوحيد داخله هو "" لعلامة الاقتباس المزدوجة.
ما الفرق بين string وString في C#؟
لا فرق. string هي الكلمة المحجوزة في C# التي تمثّل اسمًا مستعارًا لنوع .NET System.String، تمامًا كما أن int اسم مستعار لـ System.Int32. العُرف أن تستخدم string في التصريحات وstring.IsNullOrEmpty(...) في الاستدعاءات الساكنة، لكن الاثنين يُترجمان إلى الشيء نفسه تمامًا.
ما محارف الهروب التي تدعمها C#؟
\n سطر جديد، و\r إرجاع العربة، و\t جدولة، و\\ شرطة مائلة عكسية، و\" علامة اقتباس مزدوجة، و\' علامة اقتباس مفردة، و\0 المحرف الفارغ، و\uXXXX محرف UTF-16 برمزه الست عشري، و\U0001F600 محرف برمز من 8 خانات (يصبح زوجًا بديلًا)، و\a تنبيه، و\b مسح للخلف، و\f تغذية صفحة، و\v جدولة عمودية، و\e (C# 13) محرف الهروب. التسلسل غير المعروف مثل \d خطأ ترجمة (CS1009)، ولهذا تُكتب التعابير النمطية عادة كنصوص حرفية verbatim.