ذات مرة على Stack Overflow: لعنة السلاسل الطويلة في C#
\n\nتخيل الموقف. أنت تكتب في C# ملف JSON إعدادات، استعلام SQL، أو لنقل قالب HTML مباشرة في الكود. السلسلة تصبح طويلة، قبيحة، وغير قابلة للقراءة تمامًا. تضغط على Enter لنقل النص... وتحصل على خطأ في الترجمة. مألوف؟
\n\nسؤال "Multiline string literal in C#" على Stack Overflow حصد عشرات الآلاف من المشاهدات. وهذا ليس من قبيل الصدفة. لفترة طويلة، لم تكن C# اللغة الأكثر ترحيبًا للعمل مع النصوص متعددة الأسطر. لكن الأوقات تتغير. في هذه المقالة، سننتقل من الحلول المؤقتة إلى الحلول الأنيقة التي ظهرت في C# 11.
\n\nإذا كنت تكتب بلغة C# وتعمل مع القيم النصية متعددة الأسطر، فهذه المادة ستوفر لك ساعات من البحث في Google. هيا بنا!
\n\nالمشكلة: لماذا الضغط على Enter فكرة سيئة؟
\n\nفي C# (كما في C++)، القيمة النصية هي سلسلة من الأحرف محصورة بين علامتي اقتباس. فاصل السطر داخل علامات الاقتباس هذه هو خطأ نحوي. المترجم ببساطة لن يفهم أين تنتهي السلسلة.
\n\nإليك كيف لا يجب أن تفعل:
\n\n// خطأ في الترجمة!\nstring query = "SELECT * FROM Users\nWHERE Age > 18\nORDER BY Name";\n\nسيرى المترجم "SELECT * FROM Users — وهذا كل شيء. بعد ذلك يأتي الظلام. في الماضي، كان المطورون يتدبرون أمرهم كما يستطيعون. دعنا نستعرض تطور الحلول.
الطريقة القديمة: السلسلة الحرفية (Verbatim string @) — المنقذ
\n\nأول ما يتبادر إلى الذهن هو القيمة النصية الحرفية (verbatim string literal). كل ما عليك فعله هو وضع @ قبل علامة الاقتباس الافتتاحية. هذا يعطل تفسير تسلسلات الهروب (باستثناء علامات الاقتباس المزدوجة "").
لكن هناك فارق بسيط: المسافات البادئة تصبح أيضًا جزءًا من السلسلة.
\n\nمثال مع السلسلة الحرفية (verbatim string):
\n\nstring json = @"{\n ""name"": ""Alice"",\n ""age"": 30\n}";\nConsole.WriteLine(json);\n\nالإخراج:
\n{\n "name": "Alice",\n "age": 30\n}\n\nالإيجابيات:
\n- \n
- تعمل في جميع إصدارات C#. \n
- لا حاجة لهروب الخط المائل العكسي (
\\). \n
السلبيات:
\n- \n
- يجب مضاعفة علامات الاقتباس الداخلية (
"") — وهذا أمر فظيع إذا كان هناك الكثير من JSON. \n - المسافات البادئة (مسافات/علامات تبويب) تدخل في السلسلة النهائية. \n
- لا يمكن خلطها مباشرة مع استيفاء السلسلة (
$) (ولكن يمكن$@). \n
لا تزال هذه الطريقة شائعة، لكنها ليست مثالية للكود النظيف. حدث الاختراق الحقيقي في C# 11.
\n\nالطريقة الأحدث: القيمة النصية الخام (Raw string literal) (C# 11 و .NET 7+)
\n\nبدءًا من C# 11، لدينا القيمة النصية الخام (raw string literal) — حرفيًا "قيمة نصية أولية". إنها تحل 99% من مشاكل تعدد الأسطر.
\n\nالصيغة: ثلاث علامات اقتباس مزدوجة أو أكثر على التوالي (""").
مثال 1: JSON بسيط بدون هروب
\n\nstring json = """\n {\n "name": "Alice",\n "age": 30\n }\n """;\nConsole.WriteLine(json);\n\nالإخراج:
\n{\n "name": "Alice",\n "age": 30\n}\n\nالسحر: لا حاجة لمضاعفة علامات الاقتباس داخل السلسلة! المترجم يفهم أن السلسلة انتهت فقط عندما يرى ثلاث علامات اقتباس متتالية.
\n\nمثال 2: استعلام SQL مع مسافات بادئة
\n\nstring query = """\n SELECT \n u.Name,\n o.OrderDate\n FROM Users u\n JOIN Orders o ON u.Id = o.UserId\n WHERE o.Status = 'Active'\n ORDER BY o.OrderDate DESC\n """;\nConsole.WriteLine(query);\n\nمهم بخصوص المسافات البادئة: علامات الاقتباس الختامية (""") تحدد المستوى الأساسي للمسافة البادئة. جميع الأسطر التي تحتوي على مسافة بادئة أقل من علامات الاقتباس الختامية سيتم قصها. هذا يسمح بالحفاظ على قابلية قراءة الكود دون إرباك السلسلة بمسافات زائدة.