لماذا الأقواس المتعرجة في C# تمثل صداعًا؟
\n\nهل سبق لك أن كتبت كودًا بلغة C#، وأردت عرض نص مثل {الاسم}: {القيمة}، ولكن بدلاً من ذلك حصلت على FormatException؟ إذا كان الأمر كذلك، فأنت لست وحدك. سؤال «How to escape curly brace in String.Format» على Stack Overflow حصد عشرات الآلاف من المشاهدات. وهذا ليس من قبيل الصدفة: الأقواس المتعرجة {} في C# لها معنى خاص - فهي تشير إلى مكان لاستبدال المتغيرات.
ولكن ماذا تفعل إذا كنت بحاجة إلى عرض الأقواس نفسها كرموز عادية؟ على سبيل المثال، لـ JSON، القوالب، توليد الكود، أو ببساطة لتنسيق تقرير بشكل جميل؟ اليوم سنشرح هذا الموضوع من الألف إلى الياء: من الهروب البسيط إلى الحيل المتقدمة باستخدام StringBuilder وتداخل السلاسل.
كيفية الهروب من الأقواس المتعرجة: القاعدة الأساسية
\n\nالإجابة بسيطة وأنيقة: قم بمضاعفة القوس. إذا كنت تريد عرض قوس فتح واحد {، اكتب {{. وللقوس الإغلاق }، اكتب }}. ستفهم C# أن هذا ليس مكانًا للاستبدال، بل رمز عادي.
إليك أبسط مثال:
\n\nstring result = string.Format("القيمة بين الأقواس المتعرجة: {{0}}", 42);\nConsole.WriteLine(result);\n// الإخراج: القيمة بين الأقواس المتعرجة: {0}\n\nلاحظ: {{0}} ليس مكانًا للاستبدال، بل زوج من الأقواس المهربة بداخله الرقم 0. إذا كتبنا {0}، لكنا حصلنا على قيمة المتغير (الرقم 42).
خطأ شائع للمبتدئين
\n\nغالبًا ما يكتب المبتدئون هكذا:
\n\n// خطأ!\nstring bad = string.Format("مرحبًا، {name}!", name);\n// FormatException: Input string was not in a correct format.\n\nلماذا؟ لأن C# تتوقع فهرسًا رقميًا داخل الأقواس ({0}، {1})، وليس اسم متغير. للأسماء، يجب استخدام تداخل السلاسل (موضح أدناه) أو تحديد الفهارس بشكل صريح.
أمثلة عملية: من البسيط إلى المعقد
\n\nدعنا نستعرض عدة سيناريوهات حقيقية حيث يكون هروب الأقواس ضروريًا.
\n\n1. عرض JSON أو XML لأغراض التصحيح
\n\nتخيل أنك تكتب مسجل (logger) وتريد عرض سلسلة JSON مع استبدال القيمة:
\n\nint userId = 101;\nstring json = string.Format("{{\\"userId\\": {0}, \\"name\\": \\"Alice\\"}}", userId);\nConsole.WriteLine(json);\n// الإخراج: {"userId": 101, "name": "Alice"}\n\nهنا، {{ و }} تنشئ الأقواس المتعرجة الخارجية لـ JSON، بينما {0} تستبدل الرقم.
2. توليد قوالب الكود
\n\nلنفترض أنك تكتب مولد كود بلغة C#. تحتاج إلى إنشاء سلسلة تحتوي على قالب بلغة أخرى (مثل Python أو JavaScript):
\n\nstring template = string.Format("def {0}():\\n return {{0}}", "calculate");\nConsole.WriteLine(template);\n// الإخراج:\n// def calculate():\n// return {0}\n\nلاحظ: {{0}} في سلسلة الإخراج لم يعد مكانًا للاستبدال في C#، بل جزء من الكود المُنشأ (مثل Python).
3. التنسيق مع عدة أماكن استبدال وأقواس
\n\nعند الحاجة إلى مزج الاستبدالات والهروب، الأهم هو عدم الخلط بين الفهارس:
\n\nstring name = "Bob";\nint age = 30;\nstring message = string.Format("المستخدم {{ {0} }} (العمر: {1})", name, age);\nConsole.WriteLine(message);\n// الإخراج: المستخدم { Bob } (العمر: 30)\n\nهنا، {{ يعطي {، }} يعطي }، و {0} و {1} يستبدلان القيم.
بدائل String.Format: تداخل السلاسل و StringBuilder
\n\nعلى الرغم من أن string.Format كلاسيكي، إلا أن هناك طرقًا أكثر ملاءمة في C# الحديثة. دعنا نقارن.
تداخل السلاسل (C# 6+)
\n\nالتداخل هو سحر $ قبل السلسلة. إنه أكثر قابلية للقراءة، لكن هروب الأقواس يبقى