سازوکارهای قالببندی رشتهها در C#/.NET بسیار گوناگوناند: از پیوند سادهٔ اشیا گرفته تا فراخوانی متد بازنویسیشدهٔ object.ToString() و تا استفاده از ICustomFormatter (که در این تمرین به آن پرداخته نشده است).
دو سازوکار رایجتر برای قالببندی رشتهها درونیابی رشته و String.Format() هستند. اگر پیچیدگیهایی مثل چندخطی بودن در کار باشد، از کلاس StringBuilder (cross-ref-tba) هم میتوان برای ساختن رشته استفاده کرد.
ToString()
System.Object() که همهٔ کلاسها و ساختارها از آن ارث میبرند، متد ToString() دارد. برای نمونه، new DateTime(2019, 5, 23).ToString() رشتهٔ «05/23/2019 00:00:00» را تولید میکند (روی ریسهای با فرهنگ ایالات متحده؛ پایین را ببینید). موقعیتهایی مثل پیوند رشتهها وجود دارد که در آنها این متد ToString() پیشفرض ممکن است بهصورت ضمنی فراخوانی شود؛ "" + new DateTime(2019, 5, 23) هم همان نتیجه را میدهد.
علاوه بر متد ToString() پیشفرض، نوعهایی که قالببندی برایشان مهم است، سربارگذاریهایی دارند که یک رشتهٔ قالب یا حتی یک تأمینکنندهٔ قالب میگیرند. در BCL (کتابخانهٔ کلاسهای پایه) بهویژه اینها عددها، تاریخها، enumها و GUIDها هستند.
String.Format() رشتهای میگیرد (که در مستندات قالب ترکیبی نامیده میشود) متشکل از متن ثابت و جانگهدارها (که در مستندات آیتمهای قالب نامیده میشوند) بههمراه تعدادی آرگومان. مقدار بازگشتی هر آیتم قالب را با آرگومان متناظرش حل میکند و مقادیر حلشده را با متن ثابت ترکیب میکند.
string.Format("I had {0} bitcoins on {1}, the day I forgot my password.", 55.5, new DateTime(2010, 2, 25))
// => "I had 55.5 bitcoins on 2/25/2010 00:00:00, the day I forgot my password." - US settings
«Format() ممکن است جایی انتخاب بهتری از درونیابی باشد: وقتی قالب بهعنوان نوعی الگو در چندین عبارت به کار میرود، یا وقتی آوردن قالب و عبارتهایی که باید قالببندی شوند بیش از اندازه دستوپاگیر است، مثل جایی که [رشتههای تحتاللفظی][verbatim-strings] در میان باشند.
این سازوکار در اصطلاح قالببندی ترکیبی نامیده میشود.
فهرست کاملتری از متدهای تولید رشته که از قالببندی ترکیبی بهره میبرند در این مقاله آمده است.
رشتههای درونیابیشده با $ شروع میشوند و عبارتهای زمان اجرا را داخل آکولاد در بر میگیرند. آیتم قالب این نحوهٔ نگارش را دارد: $"{<interpolationExpression>[,<alignment>][:<formatString>]}". این رشتهها دیگر نیازی به فهرست جداگانهای از آرگومانها باقی نمیگذارند. نتیجه از نظر کارکرد با سازوکار String.Format() همارز است.
عبارت میتواند هر چیزی را که در محدودهٔ دید باشد در بر بگیرد. همترازی طول «فیلد»ی است که متن در آن قرار میگیرد. اگر همترازی مثبت باشد، متن از سمت چپ با فاصله پر میشود و اگر منفی باشد، فاصلهها سمت راست متن اضافه میشوند.
var loadsOf = 55.5;
var thatDay = new DateTime(2010, 2, 25);
$"I had {loadsOf} bitcoins on {thatDay}, the day I forgot my password."
// => "I had 55.5 bitcoins on 2/25/2010 00:00:00, the day I forgot my password." - US settings
متنی که داخل آکولاد میآید، چه جانگهدار در قالب ترکیبی و چه عبارت درونیابیشده در درونیابی رشته، آیتم قالب نامیده میشود.
یک آیتم قالب میتواند حداکثر از ۳ بخش تشکیل شود. بخش اول همان عبارت یا جانگهدار آرگومان است که اجباری است و در کد نمونهٔ بالا دیده میشود. علاوه بر آن، یک همترازی اختیاری (که با ویرگول، «,»، معرفی میشود) و یک رشتهٔ قالب اختیاری (که با دونقطه، «:»، معرفی میشود) وجود دارد.
{<interpolationExpression>[,<alignment>][:<formatString>]}
همترازی طول «فیلد»ی را مشخص میکند که متن در آن قرار میگیرد؛ اگر همترازی مثبت باشد، از سمت چپ و اگر منفی باشد از سمت راست با فاصله پر میشود.
رشتهٔ قالب شکل خروجی متن را مشخص میکند؛ مثلاً اینکه برای یک عدد جداکنندهٔ هزارگان درج شود یا اینکه فقط بخش تاریخ یک شیء DateTime خروجی گرفته شود.
کد زیر نمایش بخش تاریخ یک شیء DateTime و یک عدد اعشاری را به شکل نمایی نشان میدهد.
var loadsOf = 55.5;
var thatDay = new DateTime(2010, 2, 25);
$"I had {loadsOf:E} bitcoins on {thatDay:d}, the day I forgot my password."
// => I had 5.550000E+001 bitcoins on 02/25/2010, the day I forgot my password. - US settings
string.Format(
"I had {0:E} bitcoins on {1:d}, the day I forgot my password.",
loadsOf, thatDay)
// => I had 5.550000E+001 bitcoins on 02/25/2010, the day I forgot my password. - US settings
برای عددها و تاریخها هم قالببندی استاندارد هست و هم سفارشی. تفاوت مهمی بین سفارشی و استاندارد نیست، جز اینکه این فرصت را دارید که رشتههای قالب سفارشی را از کاراکترهای قالب بسازید. «سفارشی» در این بافت هیچ ارتباطی با رابط ICustomFormatter ندارد؛ آن رابط وقتی به کار میرود که قالببند سفارشی خودتان را مینویسید.
کتابخانهٔ کلاسهای پایه (BCL) دو قالببند ارائه میدهد: DateTimeFormatInfo و NumberFormatInfo و شش گروه رشتهٔ قالب.
فهرستهای گوناگون رشتههای قالب در ادامه آمده است:
رشتههای قالب Enum و GUID را میتوان در دستهٔ استاندارد به شمار آورد. هرچند enum و GUID سربارگذاریهایی از ToString() دارند که یک IFormatProvider میگیرند، روشن نیست که این کار چه اثری دارد.
در این کتابخانه تلاش شده است تا اندکی انسجام به رشتههای قالب دمیده شود (فراتر از این واقعیت که آنها بهصورت رشته نمایش داده میشوند). این تلاش برای انسجام را در رشتههای استاندارد میبینیم. در واقع، شما بهعنوان برنامهنویس بهندرت به تفاوت رشتههای استاندارد و سفارشی اهمیت میدهید. هرچند کار خوبی است که اگر برای کلاسهای خودتان قالببند مینویسید و کلاسهایتان چنین میطلبند، همان رشتههای استاندارد موجود را دنبال کنید؛ با این حال میتوانید این تفاوت را با خیال راحت نادیده بگیرید.
هر ریسهٔ اجرا یک فرهنگ پیشفرض Thread.CurrentThread.CurrentCulture دارد که در نمونهای از CultureInfo کپسوله شده است. فرهنگ ریسه تعیین میکند که تاریخها و عددها بهصورت پیشفرض و با توجه به تفاوتهای منطقهای چگونه قالببندی شوند؛ تفاوتهایی مثل تفاوت قالب متعارف تاریخ میان بریتانیا DD/MM/YYYY و ایالات متحده MM/DD/YYYY.
CultureInfo رابط IFormatProvider را پیادهسازی میکند که میتوان آن را به بعضی سربارگذاریهای String.Format() فرستاد. با این کار میتوان فرهنگ ریسه را جایگزین کرد.