C# Geeks (.NET) – Telegram
🪄 جادوی اعداد در #C :
نوشتن اعداد مثل یک حرفه‌ای (Literals, Suffixes & More)
فکر می‌کنی نوشتن 1000 تو سی‌شارپ همیشه به معنی int هست؟ یا چطور به کامپایلر بفهمونیم منظورمون یه عدد decimalئه نه double؟

اینا جزئیات و "فوت کوزه‌گری" هستن که فرق کدنویس معمولی و حرفه‌ای رو مشخص می‌کنه. بزن بریم این ترفندها رو یاد بگیریم!

👓 خوانایی کد با لیترال‌های حرفه‌ای
نوشتن اعداد، فقط مقدارشون نیست؛ خوانایی هم مهمه!

جداکننده ارقام (_): برای اعداد بزرگ، می‌تونید از آندرلاین برای جدا کردن ارقام و خوانایی بیشتر استفاده کنید. کامپایلر این آندرلاین‌ها رو نادیده می‌گیره.
int bigNumber = 1_000_000; // خیلی خواناتر از 1000000
var binaryData = 0b1010_1011_1100;


مبنای شانزده (Hexadecimal): با پیشوند 0x، می‌تونید اعداد رو در مبنای ۱۶ بنویسید. این برای کار با رنگ‌ها، فلگ‌ها و عملیات سطح پایین خیلی کاربردیه.
int redColor = 0xFF0000;


مبنای دو (Binary): با پیشوند 0b، می‌تونید مستقیماً عدد رو به صورت باینری وارد کنید.
var filePermissions = 0b110_110_100; // rwx-wx--


🏷 پسوندها (Suffixes): تعیین تکلیف برای کامپایلر!
بعضی وقتا کامپایلر خودش نوع عدد رو حدس میزنه (که بهش میگیم Type Inference)، ولی گاهی ما باید حرف آخر رو بزنیم! اینجاست که پسوندها وارد میشن.

مهم‌ترین‌هاشون اینان:
F برای float

اگه این پسوند رو نذارید، کامپایلر عدد اعشاری شما رو double در نظر می‌گیره و کدتون خطا میده چون double به راحتی به float تبدیل نمیشه.
// float f = 4.5; //   کامپایل نمیشه!
float f = 4.5F; // درسته!


M برای decimal

این یکی فوق‌العاده مهمه. برای تمام محاسبات مالی و پولی، باید از decimal استفاده کنید و برای مقداردهی بهش، حتماً از پسوند M استفاده کنید.
// decimal balance = 100.99; //  کامپایل نمیشه!
decimal balance = 100.99M; // درسته!


L برای long و U برای unsigned

این پسوندها کمتر ضروری هستن، چون معمولاً کامپایلر می‌تونه نوعشون رو حدس بزنه یا به صورت خودکار تبدیل کنه. ولی خوبه که بدونید وجود دارن.
long bigNum = 9_000_000_000L; // با L بهش میگیم این یه عدد خیلی بزرگه

شما چطور اعداد رو می‌نویسید؟
اینا فقط یه سری قاعده خشک و خالی نیستن، ابزارهایی برای نوشتن کد دقیق‌تر و خواناتر هستن.

🔖 هشتگ‌ها :
#CSharp
#CodingTips
#Literals
🎲 قوانین بازی با اعداد در #C :
همه چیز درباره تبدیل‌های عددی (Casting)

تا حالا فکر کردید وقتی یه int رو توی یه long می‌ریزید، یا یه double رو به زور تو یه int جا می‌دید، پشت صحنه چه اتفاقی میفته؟

این تبدیل‌ها (Conversions) قوانین خودشون رو دارن و ندونستن این قوانین، می‌تونه به از دست رفتن داده و باگ‌های وحشتناک ختم بشه. بزن بریم این قوانین رو یک بار برای همیشه یاد بگیریم.

نوع اول: تبدیل‌های امن و ضمنی (Implicit)

این تبدیل‌ها مثل ریختن آب از یه لیوان کوچیک تو یه سطل بزرگه؛ کاملاً امن، بدون دردسر و بدون از دست رفتن حتی یک قطره آب!

وقتی نوع داده مقصد، گنجایش تمام مقادیر ممکن در نوع داده مبدأ رو داشته باشه، #C خودش هوشمندانه و به صورت خودکار این تبدیل رو انجام میده.

int myInt = 12345;

// int (32-bit) به راحتی در long (64-bit) جا میشه
long myLong = myInt;

// int (عدد صحیح) به راحتی به double (عدد اعشاری) تبدیل میشه
double myDouble = myInt;

float myFloat = 123.45F;

// float (32-bit) به راحتی در double (64-bit) جا میشه
double anotherDouble = myFloat;


⚠️ نوع دوم: تبدیل‌های خطرناک و صریح (Explicit Casting)
حالا برعکسش رو تصور کنید: می‌خواید آب یه سطل بزرگ رو تو یه لیوان کوچیک جا بدید. احتمال اینکه آب سرریز بشه و بخشی ازش از دست بره، خیلی زیاده!

اینجا دیگه سی‌شارپ به شما اجازه نمیده این کار رو خودکار انجام بدید. شما باید با مسئولیت خودتون و با استفاده از Casting (قرار دادن نوع مقصد داخل پرانتز)، به کامپایلر بگید: "می‌دونم دارم چیکار می‌کنم و ریسکش رو می‌پذیرم!"

long bigNum = 3_000_000_000L;
double myDouble = 12345.6789;

// برای جا دادن long در int، باید کست کنیم
// اگه عدد بزرگ باشه، داده از دست میره!
int myInt = (int)bigNum;

// برای جا دادن double در int، باید کست کنیم
int anotherInt = (int)myDouble; // مقدارش میشه 12345


💣 دو تله مرگبار در تبدیل‌های صریح
وقتی کست می‌کنید، حواستون به این دوتا تله باشه:

بریده شدن اعشار (Truncation):
وقتی یه عدد اعشاری (double یا float) رو به یه عدد صحیح (int) کست می‌کنید، بخش اعشاری عدد گرد نمیشه، بلکه وحشیانه بریده و حذف میشه!
double price = 99.99;
int priceAsInt = (int)price; // مقدارش میشه 99، نه 100!


از دست رفتن دقت (Precision Loss):
گاهی اوقات، حتی در تبدیل‌های امن (مثل int به float)، ممکنه دقت رو از دست بدید. float می‌تونه اعداد خیلی بزرگتری رو نشون بده، ولی دقتش در جزئیات کمتر از int هست.

int bigInt = 100_000_001;

// اینجا مقدار حفظ میشه، ولی دقت از بین میره
float myFloat = bigInt;

// وقتی برمی‌گردونیم، می‌بینیم که عدد تغییر کرده!
int convertedInt = (int)myFloat; // مقدارش میشه 100_000_000


🔖 هشتگ‌ها :
#CSharp
#CodingTips
#Casting
💡 نکته سریع #C :
راز عملگرهای حسابی با تایپ‌های کوچک!


همه ما با عملگرهای حسابی مثل + و * آشناییم. ولی آیا می‌دونستید یه نکته‌ی جالب و مهم در موردشون موقع کار با تایپ‌های کوچیکی مثل byte و short وجود داره؟

فرض کنید می‌خواید دو تا byte رو با هم جمع کنید. چه اتفاقی میفته؟
byte b1 = 10;
byte b2 = 20;

// انتظار داریم این کد کار کنه، ولی...
// این خط کامپایل نمیشه!
byte result = b1 + b2;


چرا خطا میده؟
چون در #C، وقتی عملیات حسابی روی تایپ‌های کوچکتر از int (مثل byte یا short) انجام میشه، اون‌ها اول به صورت خودکار به int تبدیل میشن و حاصل عملیات هم یک int خواهد بود!

بنابراین، کد صحیح این شکلیه:
//  درسته! حاصل جمع دو بایت، یک int است.
int result = b1 + b2;


دلیل این کار چیه؟
این رفتار برای بهینه‌سازی و سادگی در سطح پردازنده و CLR طراحی شده. کار کردن با int (که معمولاً اندازه کلمه پردازنده است) سریع‌تر و بهینه‌تره.

حالا اگه حتماً نتیجه رو تو یه byte می‌خواید چی؟
باید خودتون صراحتاً نتیجه رو کست کنید (و البته حواستون به سرریز شدن یا Overflow باشه!):

//  درسته (با مسئولیت خودتان!)
byte result = (byte)(b1 + b2);

حرف آخر: یادتون باشه، حاصل عملیات حسابی روی تایپ‌های کوچیک، همیشه یه intئه! دونستن همین نکته کوچیک، جلوی خیلی از خطاهای کامپایل ناگهانی رو می‌گیره.

🔖 هشتگ‌ها :
#CSharp
#QuickTip
💣 تله‌های کار با اعداد صحیح :
تقسیم، Overflow و checked
فکر می‌کنید 2÷5 همیشه حاصلش 2.5 میشه؟ یا int.MaxValue + 1 یه عدد خیلی بزرگه؟ اگه جوابتون "بله" هست، این پست برای شماست!

تو دنیای اعداد صحیح، تله‌های پنهانی وجود داره که می‌تونه بی‌صدا و بدون هیچ هشداری، کدهای شما رو به فنا بده. بزن بریم این خطرات رو بشناسیم و یاد بگیریم چطور ازشون جلوگیری کنیم.
🔪 تله اول: تقسیم صحیح و سلاخی اعشار!

وقتی دو عدد صحیح رو بر هم تقسیم می‌کنید، سی شارپ بخش اعشاری حاصل رو گرد نمی‌کنه، بلکه به سادگی حذف (Truncate) می‌کنه.

این یعنی نتیجه‌ی تقسیم، همیشه یه عدد صحیحه.

int a = 5;
int b = 2;

// انتظار داریم حاصل 2.5 باشه، ولی اعشار حذف میشه!
int result = a / b;
Console.WriteLine(result); // خروجی: 2


نکته حرفه‌ای: تقسیم بر متغیر صفر
int x=0;
5/x;

باعث خطای زمان اجرا(DivideByZeroException) میشه، ولی تقسیم بر خودِ صفر لیترال ;5/0 باعث خطای زمان کامپایل میشه!
👻 تله دوم (و خطرناک‌ترین) :
سرریز شدن سایلنت (Silent Overflow)

این یکی کابوس برنامه‌نویس‌هاست! تصور کنید کیلومترشمار یه ماشین قدیمی بعد از اینکه به 999999 میرسه، دوباره صفر میشه. اعداد صحیح هم به صورت پیش‌فرض دقیقاً همین رفتار رو دارن!

اگه یه عملیات حسابی از حداکثر ظرفیت یه نوع داده بیشتر بشه، هیچ خطایی رخ نمیده! نتیجه به صورت سایلنت به ابتدای محدوده برمی‌گرده (Wraparound).

int i = int.MaxValue; // بزرگترین عدد ممکن برای int (حدود ۲ میلیارد)

i = i + 1; // یک واحد بهش اضافه می‌کنیم

// انتظار داریم خطا بده یا یه عدد بزرگتر بشه، ولی...
// عدد از ماکسیمم به مینیمم جهش می‌کنه!
Console.WriteLine(i == int.MinValue); // خروجی: True!


این رفتار سایلنت می‌تونه باعث ایجاد باگ‌های منطقی بسیار خطرناک و غیرقابل ردیابی در محاسبات مالی، علمی و امنیتی بشه.
🛡 راه نجات :
فرشته نگهبان به نام checked


خوشبختانه، #C راه حل این فاجعه سایلنت رو در اختیار ما گذاشته.

اپراتور checked.

هر عبارتی که داخل checked قرار بگیره، در صورت سرریز شدن، به جای رفتار سایلنت، یک خطای واضح و مشخص به نام OverflowException پرتاب می‌کنه.

int a = 1_000_000;
int b = 1_000_000;

try
{
// این عبارت رو برای سرریز شدن چک کن
// حاصل ضرب از ظرفیت int بیشتر میشه
int c = checked(a * b); // اینجا استثنا (Exception) رخ میده!
Console.WriteLine(c);
}
catch (OverflowException)
{
Console.WriteLine("Overflow detected! Calculation aborted.");
}


نکته حرفه‌ای: می‌تونید این قابلیت رو در تنظیمات پروژه برای کل برنامه فعال کنید و هرجا که خواستید رفتار سایلنت رو داشته باشید، از unchecked استفاده کنید.

و اما unchecked: وقتی می‌خوایم خطر کنیم!
int x = int.MaxValue;

// این عملیات چک نمیشه و به حالت سایلنت برمی‌گرده
int y = unchecked(x + 1);

unchecked
{
// تمام عبارات این بلوک هم چک نمیشن
int z = x + 1;
}


🤔 حرف حساب و تجربه شما
شناختن این رفتارها و استفاده از checked، مرز بین کدنویسی آماتور و حرفه‌ایه.

🔖 هشتگ‌ها :
#CSharp
#DotNet
#Bugs
💡 نکته سریع #C :
تفاوت ++x و x++ چیه؟


یکی از سوالای کلاسیک و در عین حال فنی تو مصاحبه‌های سی‌شارپ، تفاوت بین ++x (حالت Postfix) و x++ (حالت Prefix) هست.

هر دوتاشون در نهایت مقدار x رو یکی زیاد می‌کنن، ولی "زمان" این افزایش، زمین تا آسمون با هم فرق می‌کنه و همین می‌تونه رفتار کد شما رو کاملاً عوض کنه.

حالت Postfix (اول بده، بعداً زیاد کن!):++x

در این حالت، اول مقدار فعلی و قدیمی x در عبارت استفاده میشه و بعد از اینکه اون خط تموم شد، مقدار x یکی زیاد میشه.

فکر کنید x یه چک بانکیه. شما اول چک رو با همون مبلغ فعلی به طرف میدین (مقدار رو برمی‌گردونین)، بعد که کارتون تموم شد، تو حساب خودتون یکی بهش اضافه می‌کنید.

مثال:
int x = 5;

// اینجا اول مقدار فعلی x (یعنی 5) چاپ میشه
Console.WriteLine(x++); // خروجی: 5

// حالا که خط بالا تموم شد، x یکی زیاد شده
Console.WriteLine(x); // خروجی: 6


حالت Prefix (اول زیاد کن، بعداً بده!): x++

اینجا برعکسه. اول مقدار x یکی زیاد میشه و بعد، مقدار جدید و افزایش‌یافته در عبارت استفاده میشه.

اینجا شما اول تو حساب خودتون یکی به مبلغ چک اضافه می‌کنید، بعد چک جدید رو با مبلغ افزایش‌یافته به طرف میدین (مقدار جدید رو برمی‌گردونین).

مثال:

int y = 5;

// اینجا اول y یکی زیاد میشه (میشه 6)، بعد مقدار جدیدش چاپ میشه
Console.WriteLine(++y); // خروجی: 6

// y که قبلاً زیاد شده بود، هنوز همون 6 هست
Console.WriteLine(y); // خروجی: 6


حرف آخر:

x++ (Postfix):

اول مقدار فعلی رو برمی‌گردونه، بعد x رو آپدیت می‌کنه.

++x (Prefix):

اول x رو آپدیت می‌کنه، بعد مقدار جدید رو برمی‌گردونه.

دونستن همین نکته کوچیک، به خصوص در حلقه‌ها و محاسبات پیچیده، خیلی به کار میاد و جلوی باگ‌های منطقی رو می‌گیره!

🔖 هشتگ‌ها :
#CSharp
#QuickTip
#DotNet
🌀 دنیای عجیب اعداد اعشاری: Infinity، NaN و تله‌های مقایسه!
فکر می‌کنید تقسیم بر صفر همیشه خطا میده؟ یا یه مقدار همیشه با خودش برابره؟ تو دنیای اعداد اعشاری (float و double)، قوانین فیزیک یه جور دیگه‌ست!

برخلاف اعداد صحیح، این نوع‌ها مقادیر ویژه‌ای دارن که برای مدیریت شرایط خاص ریاضی طراحی شدن. بیاید باهاشون آشنا بشیم.
♾️ بی‌نهایت (Infinity):
وقتی تقسیم بر صفر خطا نیست!
در دنیای اعداد صحیح، تقسیم بر صفر یه گناه نابخشودنیه و باعث خطای DivideByZeroException میشه. اما در دنیای اعداد اعشاری، اینطور نیست!

تقسیم یک عدد غیرصفر بر صفر، منجر به تولید بی‌نهایت مثبت یا منفی میشه و برنامه به کارش ادامه میده.

Console.WriteLine(1.0 / 0.0);   // خروجی: Infinity
Console.WriteLine(-1.0 / 0.0); // خروجی: -Infinity
Console.WriteLine(1.0 / -0.0); // خروجی: -Infinity


این رفتار در محاسبات علمی و گرافیکی که با حدود و مقادیر خیلی بزرگ سر و کار داریم، بسیار مفیده.
پوچی مطلق (NaN):
وقتی جواب "عدد نیست"!

NaN مخفف "Not a Number" (عدد نیست) هست. این مقدار ویژه، حاصل عملیات ریاضی تعریف نشده یا نامعتبره.


مثلاً تقسیم صفر بر صفر، یا کم کردن بی‌نهایت از بی‌نهایت، جوابی نداره و سی‌شارپ به جای خطا دادن، حاصل رو NaN برمی‌گردونه.

Console.WriteLine(0.0 / 0.0);                  // خروجی: NaN
Console.WriteLine((1.0 / 0.0) - (1.0 / 0.0)); // خروجی: NaN


NaN

مثل یه پرچمه که میگه "من نتونستم این محاسبه رو انجام بدم، ولی نذاشتم برنامه کرش کنه".
🪤 تله بزرگ: NaN == NaN همیشه False است!
این یکی از عجیب‌ترین و مهم‌ترین نکاتیه که باید بدونید. طبق استاندارد IEEE 754، یک مقدار NaN هیچوقت با هیچ مقدار دیگه‌ای، حتی یک NaN دیگه، برابر نیست!

منطقش اینه که یک "مقدار نامشخص" نمی‌تونه با یک "مقدار نامشخص" دیگه برابر باشه.

// این کد شما رو به اشتباه میندازه!
Console.WriteLine(0.0 / 0.0 == double.NaN); // خروجی: False


پس اگه بخواید با == چک کنید که آیا متغیری NaN هست یا نه، همیشه جواب false می‌گیرید و این می‌تونه باعث باگ‌های خیلی بدی بشه.
راه حل: پس چطور NaN رو چک کنیم؟
راه درست و تنها راه مطمئن برای چک کردن NaN، استفاده از متدهای استاتیک double.IsNaN() یا float.IsNaN() هست.

double result = 0.0 / 0.0;

// روش اشتباه
if (result == double.NaN) { /* این کد هرگز اجرا نمیشه */ }

// روش درست
if (double.IsNaN(result))
{
Console.WriteLine("The result is indeed NaN!");
}


🤔 حرف حساب و تجربه شما
درک این مقادیر ویژه، شما رو از خیلی از باگ‌های محاسباتی پنهان نجات میده.

شما تا حالا تو محاسباتتون به Infinity یا NaN برخوردید؟ یا از تله مقایسه NaN خبر داشتید؟ این رفتار عجیب اعداد اعشاری کجا به کارتون اومده یا براتون دردسر ساخته؟

تجربه‌هاتون رو کامنت کنید! 👇

🔖 هشتگ‌ها :
#CSharp
#CodingTips
#DotNet
#FloatingPoint
#NaN
🎭 تله‌های برابری (==) در #C:
مقایسه مقدار در برابر مقایسه آدرس!
فکر می‌کنید اپراتور == همیشه مقادیر رو با هم مقایسه می‌کنه؟ اگه دو تا شیء داشته باشیم که محتوای داخلی‌شون یکسانه، آیا با هم برابرن؟

جواب تو سی‌شارپ همیشه "بله" نیست! این یکی از اون تله‌های کلاسیکه که ریشه‌ش مستقیم به تفاوت Value Type و Reference Type برمی‌گرده. بیاید این موضوع مهم رو یک بار برای همیشه روشن کنیم.

دنیای ساده: مقایسه Value Typeها
برای Value Typeها (مثل int, struct, bool)، اپراتور == دقیقاً همون کاری رو می‌کنه که انتظار دارید: مقدار واقعی داخل متغیرها رو با هم مقایسه می‌کنه. ساده و قابل پیش‌بینی.
int x = 5;
int y = 10;
int z = 5;

// آیا مقدار x با y برابره؟ نه.
Console.WriteLine(x == y); // خروجی: False

// آیا مقدار x با z برابره؟ بله.
Console.WriteLine(x == z); // خروجی: True
دنیای پیچیده:
مقایسه Reference Typeها

اینجاست که داستان جالب میشه! برای Reference Typeها (مثل class)، اپراتور == به صورت پیش‌فرض، محتوای داخلی آبجکت‌ها رو مقایسه نمی‌کنه.

در عوض، آدرس اون‌ها در حافظه رو مقایسه می‌کنه. یعنی از خودش می‌پرسه: "آیا این دو متغیر، به یک آبجکت یکسان در حافظه اشاره می‌کنن؟"

یادتونه گفتیم Reference Type مثل کلید یه خونه‌ست؟ اینجا == چک نمی‌کنه که آیا دو تا خونه دکوراسیون یکسانی دارن یا نه. فقط چک می‌کنه که آیا این دو تا کلید، برای یک خونه‌ی یکسان هستن یا برای دو تا خونه‌ی جدا که فقط شبیه هم ساخته شدن.

مثال کلاس Dude رو ببینید:

public class Dude
{
public string Name;
public Dude(string n) { Name = n; }
}

// ...

// ما دو تا آبجکت جداگانه در حافظه می‌سازیم که هر دو اسمشون "John" هست
Dude d1 = new Dude("John");
Dude d2 = new Dude("John");

// اینجا d3 کلید خونه‌ی d1 رو می‌گیره، خونه جدیدی ساخته نمیشه
Dude d3 = d1;

// آیا d1 و d2 به یک آبجکت یکسان اشاره می‌کنند؟ نه!
// (دو تا خونه جدا ولی شبیه به هم)
Console.WriteLine(d1 == d2); // خروجی: False

// آیا d1 و d3 به یک آبجکت یکسان اشاره می‌کنند؟ بله!
// (دو تا کلید برای یک خونه)
Console.WriteLine(d1 == d3); // خروجی: True
🪄 جادوی اپراتورهای شرطی #C :
از Short-Circuiting تا اپراتور سه‌تایی.
فقط یه if ساده نوشتن، کار هر کسیه. اما یه برنامه‌نویس حرفه‌ای، با استفاده از ابزارهایی مثل Short-Circuiting و اپراتور سه‌تایی، ifهای هوشمندتر، امن‌تر و خواناتری می‌نویسه.

بیاید با این جادوهای پرکاربرد آشنا بشیم.
🔌 اتصال کوتاه (Short-Circuiting):
ناجی شما از NullReferenceException
این مهم‌ترین مفهومیه‌ که در مورد اپراتورهای && (AND) و || (OR) باید بدونید.

قانون اتصال کوتاه میگه:

در یک عبارت &&، اگر قسمت اول false باشه، #C اونقدر هوشمنده که دیگه قسمت دوم رو اصلاً بررسی نمی‌کنه (چون نتیجه کل عبارت قطعاً false هست).
در یک عبارت ||، اگر قسمت اول true باشه، باز هم قسمت دوم بررسی نمیشه (چون نتیجه کل عبارت قطعاً true هست).
این فقط برای سرعت بیشتر نیست، بلکه یه تکنیک حیاتی برای جلوگیری از خطاست. به این مثال طلایی نگاه کنید:

string myString = null;

// این کد بدون اتصال کوتاه، خطای NullReferenceException میداد
// چون sb.Length روی یک متغیر null اجرا میشد.
if (myString != null && myString.Length > 0)
{
Console.WriteLine("String has content.");
}
else
{
Console.WriteLine("String is null or empty.");
}


اینجا چون myString != null برابر با false هست، #C هیچوقت به myString.Length نگاه هم نمی‌کنه و برنامه شما از یک خطای حتمی نجات پیدا می‌کنه!
اپراتور سه‌تایی (Ternary Operator ? : )
یک if-else در یک خط!
اپراتور سه‌تایی یه راه خیلی شیک و کوتاه برای نوشتن یه if-else ساده‌ست که قراره یه مقداری رو برگردونه.

ساختارش اینه:
شرط ? مقدار در صورت درستی : مقدار در صورت نادرستی

مثلاً به جای اینکه اینجوری بنویسیم:
int a = 10;
int b = 20;
int max;

if (a > b)
{
max = a;
}
else
{
max = b;
}


می‌تونیم خیلی شیک و کوتاه اینجوری بنویسیم:
int a = 10;
int b = 20;

int max = (a > b) ? a : b; // اگر a > b درست بود، a رو برگردون، وگرنه b رو
Console.WriteLine(max); // خروجی: 20
💡 نکته سریع #C :
سه راز در مورد bool که شاید نمی‌دانستید!
همه ما هر روز از bool برای شرط‌هامون استفاده می‌کنیم، ولی این نوع داده منطقی، چند تا راز کوچک و جالب داره که دونستنشون دید شما رو به سی‌شارپ عمیق‌تر می‌کنه.

بولین، عدد نیست!

برخلاف بعضی زبان‌های برنامه‌نویسی دیگه، در C# نوع bool یک نوع منطقی کاملاً مستقله و هیچ ارتباطی با اعداد نداره. شما نمی‌تونید یک bool رو به int تبدیل کنید یا برعکس. true معادل 1 نیست!

// این کدها اصلاً کامپایل نمیشن!
// int myInt = (int)true; // خطای کامپایل!
// bool myBool = (bool)1; // خطای کامپایل!


این ویژگی، جلوی بسیاری از خطاهای منطقی ناخواسته رو می‌گیره.
یک بیت یا یک بایت؟ مسئله این است!

از نظر تئوری، برای ذخیره یک مقدار bool (true یا false) فقط یک بیت حافظه کافیه. اما در عمل، CLR برای بهینگی و راحتی کار با پردازنده، برای هر متغیر bool یک بایت (۸ بیت) کامل در حافظه در نظر می‌گیره.

نکته حرفه‌ای:

اگه نیاز دارید تعداد خیلی خیلی زیادی bool رو در حافظه ذخیره کنید و فضا براتون مهمه (مثلاً در کار با فایل‌های باینری)، می‌تونید از کلاس System.Collections.BitArray استفاده کنید که برای هر مقدار، دقیقاً یک بیت مصرف می‌کنه.
bool فقط یک نام مستعاره!

مثل بقیه انواع داده پیش‌ساخته، کلمه کلیدی bool در #C فقط یک نام مستعار (alias) ساده و راحت برای نوع داده اصلی در فریم‌ورک دات‌نت یعنی System.Boolean هست.

این دو خط کد، در نهایت یک کار یکسان رو انجام میدن:

bool b1 = true;
System.Boolean b2 = true; // این همون بالاییه، فقط با اسم کاملش!


حرف آخر:
پس یادتون باشه: bool یه نوع منطقی خالصه، نه یه عدد. در حافظه یه بایت جا میگیره و فقط یه نام مستعار برای System.Boolean هست!

🔖 هشتگ‌ها :
#CSharp
#QuickTip
#DotNet
#Boolean
#CodingTips