Software Philosophy
3.46K subscribers
159 photos
41 videos
1.53K links
چکیده‌ای از مفاهیم به روز مهندسی نرم افزار برای مهندسین نرم‌افزار.
معماری نوین نرم‌افزار، تکنولوژی‌های برنامه نویسی جدید
Download Telegram
آشنایی با کلاس‌ها در زبان برنامه‌نویسی سی شارپ

#csharp_for_beginners

در زبان برنامه‌نویسی سی شارپ، کلاس‌ها (Classes) یکی از اصلی‌ترین اجزای برنامه‌نویسی شی‌ءگرا هستند. کلاس‌ها ساختارهایی هستند که به برنامه‌نویس اجازه می‌دهند اشیاء (Objects) را تعریف کرده و رفتار و داده‌های آن‌ها را سازمان‌دهی کنند. این مفهوم به ما کمک می‌کند تا برنامه‌هایی ماژولار، قابل نگهداری و قابل گسترش بنویسیم.

تعریف کلاس
یک کلاس در سی شارپ مانند یک الگو یا قالب است. این قالب ویژگی‌ها (Properties) و رفتارها (Methods)یی را تعریف می‌کند که یک شیء از آن کلاس می‌تواند داشته باشد. برای مثال، اگر بخواهیم یک کلاس به نام Car تعریف کنیم، می‌توانیم ویژگی‌هایی مانند Color یا Speed و رفتارهایی مانند Drive() یا Stop() برای آن مشخص کنیم.

مثال ساده‌ای از تعریف کلاس:

public class Car
{
public string Color;
public int Speed;

public void Drive()
{
Console.WriteLine("Driving...");
}
}


ایجاد نمونه (Instance)
برای استفاده از یک کلاس، باید از آن نمونه‌سازی کنیم. این نمونه یک شیء واقعی از کلاس است که می‌توان از آن در برنامه استفاده کرد:

Car myCar = new Car();
myCar.Color = "Red";
myCar.Drive();


سازنده‌ها (Constructors)

سازنده‌ها متدی خاص در کلاس هستند که هنگام ایجاد یک شیء جدید فراخوانی می‌شوند. آن‌ها معمولاً برای مقداردهی اولیه به ویژگی‌های شیء استفاده می‌شوند:

public class Car
{
public string Color;

// سازنده
public Car(string color)
{
Color = color;
}
}


و استفاده از آن:

Car myCar = new Car("Blue");


دسترسی و سطح دسترسی

کلمات کلیدی مانند public، private، و protected تعیین می‌کنند که اعضای کلاس از کجا قابل دسترسی هستند. به طور پیش‌فرض، اعضای کلاس private هستند، یعنی فقط از داخل خود کلاس قابل دسترسی‌اند.

وراثت (Inheritance)
یکی از ویژگی‌های قدرتمند کلاس‌ها، وراثت است. یک کلاس می‌تواند از کلاس دیگری ارث‌بری کند و ویژگی‌ها و رفتارهای آن را به ارث ببرد

public class Vehicle
{
public void Start() => Console.WriteLine("Starting...");
}

public class Car : Vehicle
{
public void Drive() => Console.WriteLine("Driving...");
}



🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍93🔥2
آموزش گام‌به‌گام دیباگ برنامه‌های C# در VS Code

#csharp_for_beginners

۱. معرفی ویدیویی
• این قسمت از مجموعه، مخصوص رفع مشکلات دیباگی که قبلاً ایجاد شده‌اند در VS Code برای پروژه‌های سی‌شارپ است.

۲. مروری بر شرایط خطا
• تمرکز بر Conditional Breakpoints (نقاط توقف شرطی) است؛ زمانی مفید که می‌خواهید در شرایط خاصی اجرای برنامه متوقف شود.
• در ویدیو، نشان داده می‌شود که چگونه این شرط‌ها گاهی به درستی کار نمی‌کنند (مثلاً خطاهایی که باعث نمی‌شوند نقطه توقف فعال شود یا شرایط نادیده گرفته می‌شود).

۳. تنظیم دقیق Breakpointها
• توضیح گام‌به‌گام نحوه افزودن یک Breakpoint شرطی با وارد کردن یک شرط مثل x == 5.
• نمایش اینکه چطور می‌توان شرط را اصلاح یا حذف کرد تا دوباره قابل‌استفاده شود.

۴. اشکالات رایج
• ممکن است VS Code یا اکستنشنی که استفاده می‌کنید، شرط را نادیده بگیرد یا اجرا را ادامه دهد.
• روش‌هایی برای رفع این مشکل بررسی می‌شود، از جمله به‌روزرسانی اکستنشن‌، تغییر پیکربندی launch.json، و راه‌اندازی مجدد جلسه دیباگ.

۵. ابزارهای کمکی و دیباگ پیشرفته
• اشاره به ویژگی‌هایی مثل Watch (مشاهده متغیرها) و Call Stack برای درک بهتر وضعیت اجرا.
• نمایش اینکه چطور Breakpoint را در کدی فعال کنیم که در چند مسیر اجرا ممکن است قابل رسیدن باشد.

۶. نکات پایانی
• توصیه به آزمایش Breakpointهای شرطی در سناریوهای ساده‌تر قبل از اعمال در کد پیچیده.
• تشویق به مطالعه مستندات VS Code و مراجع مایکروسافت برای رفع خطاهای ناشی از ناسازگاری نسخه یا پیکربندی اشتباه

🔗 ویدئوی کامل را اینجا مشاهده کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍61
معرفی کلاس <List<T در سی‌شارپ

#csharp_for_beginners

در زبان برنامه‌نویسی سی‌شارپ، مجموعه‌ها (Collections) نقش بسیار مهمی در مدیریت داده‌ها ایفا می‌کنند. یکی از رایج‌ترین و پرکاربردترین مجموعه‌های عمومی، کلاس <List<T است که در فضای نام System.Collections.Generic قرار دارد. این کلاس، یک لیست عمومی (Generic List) است که امکان ذخیره‌سازی، دسترسی و مدیریت مجموعه‌ای از عناصر از نوع مشخص‌شده را فراهم می‌کند.

تعریف کلی
public class List<T> : System.Collections.Generic.IList<T>,
System.Collections.Generic.ICollection<T>,
System.Collections.Generic.IEnumerable<T>,
System.Collections.IList,
System.Collections.ICollection,
System.Collections.IEnumerable

کلاس <List<T لیسی دینامیک است که به صورت خودکار اندازه‌اش را بر اساس داده‌های ورودی تغییر می‌دهد و برخلاف آرایه‌ها، نیازی به تعیین اندازه‌ی اولیه آن نیست.

ویژگی‌های اصلی
•عمومی بودن نوع داده: می‌توان لیستی از هر نوع داده‌ای ایجاد کرد (مثل <List<int یا <List<string ).
پشتیبانی از عملیات متنوع: افزودن، حذف، جست‌وجو، مرتب‌سازی و … به‌سادگی قابل انجام هستند.
اندازه‌ی متغیر: نیازی به تعیین اندازه در زمان تعریف نیست.
دسترسی سریع با ایندکس: مانند آرایه‌ها می‌توان به اعضای لیست با استفاده از اندیس دسترسی داشت.

نمونه کد ساده
List<string> names = new List<string>();
names.Add("Ali");
names.Add("Sara");
names.Add("Reza");

foreach (string name in names)
{
Console.WriteLine(name);
}


سازنده‌ها (Constructors)
کلاس List<T> دارای چند سازنده برای ایجاد لیست است:
• List<T>()
ایجاد یک لیست خالی.
• List<T>(IEnumerable<T>)
ایجاد لیست با استفاده از مجموعه‌ای دیگر.
• List<T>(int capacity)
تعریف ظرفیت اولیه لیست
—————————————————————

متدهای مهم کلاس List<T>
۱. Add
اضافه کردن یک عنصر به انتهای لیست.

۲. AddRange
اضافه کردن مجموعه‌ای از عناصر به لیست.

۳. Remove
حذف اولین عنصر مشخص‌شده از لیست.

۴. RemoveAt
حذف عنصری که در یک ایندکس خاص قرار دارد.

۵. Clear
پاک کردن تمام عناصر لیست و خالی کردن آن.

۶. Contains
بررسی وجود یک عنصر در لیست.

۷. IndexOf
یافتن ایندکس اولین وقوع یک عنصر مشخص.

۸. Sort
مرتب‌سازی عناصر لیست به ترتیب صعودی یا با مقایسه‌گر سفارشی.

۹. Reverse
معکوس کردن ترتیب عناصر لیست.

۱۰. ToArray
تبدیل لیست به آرایه.

۱۱. Count
گرفتن تعداد عناصر موجود در لیست (ویژگی - property).

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍75🔥3
پشته (Stack)
#csharp_for_beginners

در برنامه‌نویسی، ساختار داده‌ای پشته (Stack) یکی از رایج‌ترین و کاربردی‌ترین ساختارها برای مدیریت داده‌ها به ‌شمار می‌رود. پشته بر اساس اصل LIFO (آخرین ورودی، اولین خروجی) عمل می‌کند. در چارچوب دات‌نت، کلاس Stack در فضای نام System.Collections برای این منظور طراحی شده است

معرفی کلاس Stack
کلاس Stack (نسخهٔ غیرجنریک) در فضای نام System.Collections قرار دارد و می‌تواند انواع مختلف داده‌ها (حتی null) را در خود نگه دارد. این کلاس با استفاده از نوع object، امکان ذخیرهٔ هر نوع داده‌ای را فراهم می‌کند

متدها و ویژگی‌های اصلی
در این بخش مهم‌ترین متدها و خواص کلاس Stack را بررسی می‌کنیم:

۱. Push(object obj)
افزودن یک عنصر به بالای پشته:

Stack stack = new Stack();
stack.Push("سلام");
stack.Push(123);
stack.Push(null);


۲. Pop()

حذف و بازگرداندن عنصر بالای پشته:

object top = stack.Pop(); // آخرین مقدار افزوده‌شده را برمی‌گرداند


۳. Peek()

فقط مشاهدهٔ عنصر بالای پشته بدون حذف آن:

object top = stack.Peek();


۴. Count

تعداد عناصر موجود در پشته:

int count = stack.Count;


۵. Clear()

پاک‌سازی کامل پشته:

stack.Clear();


۶. Contains(object obj)

بررسی وجود یک عنصر خاص:

bool hasHello = stack.Contains("سلام");


نمونه‌کد کامل:
Stack myStack = new Stack();
myStack.Push("Hello");
myStack.Push("World");
myStack.Push(null);

Console.WriteLine($"تعداد: {myStack.Count}");

while (myStack.Count > 0)
Console.WriteLine(myStack.Pop());


خروجی:

تعداد: 3
null
World
Hello



🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍97👏2
صف (Queue)

#csharp_for_beginners

در برنامه‌نویسی، صف (Queue) یکی از مهم‌ترین ساختارهای داده‌ای است که بر پایه اصل اول وارد، اول خارج (FIFO) عمل می‌کند. کلاس <Queue<T در فضای نام System.Collections.Generic در دات‌نت (#C) پیاده‌سازی این ساختار را به شکلی ساده و قدرتمند فراهم کرده است.

کلاس <Queue<T از فضای نام System.Collections.Generic استفاده می‌کند و برای کار با مجموعه‌ای از عناصر از نوع مشخص (Generic) طراحی شده است. این کلاس در اسمبلی System.Collections.dll قرار دارد

ویژگی‌های اصلی
FIFO (اول وارد، اول خارج): عناصر به انتهای صف اضافه می‌شوند و از ابتدای آن حذف می‌شوند.
جنریک: می‌توانید نوع داده مورد نظر خود را هنگام ایجاد صف مشخص کنید.
کارایی بالا : استفاده بهینه از حافظه و سرعت مناسب برای صف‌هایی با حجم بالا.

متدها و اعضای مهم
Enqueue
این متد برای افزودن یک عنصر به انتهای صف استفاده می‌شود.
Dequeue
برای حذف و بازگرداندن اولین عنصر صف از این متد استفاده می‌شود. اگر صف خالی باشد، اجرای این متد منجر به بروز خطا می‌شود.
Peek
این متد بدون حذف عنصر، فقط اولین عنصر صف را بازمی‌گرداند. در صورتی که صف خالی باشد، خطا ایجاد می‌شود.
Count
این ویژگی تعداد عناصر موجود در صف را بازمی‌گرداند و فقط قابل خواندن است.
Clear
تمام عناصر موجود در صف را حذف می‌کند و صف را به وضعیت خالی برمی‌گرداند.
Contains
بررسی می‌کند که آیا یک عنصر خاص در صف وجود دارد یا خیر. مقدار برگشتی این متد یک مقدار منطقی (true یا false) است.
ToArray
تمامی عناصر موجود در صف را به یک آرایه کپی می‌کند و آن را بازمی‌گرداند.
TrimExcess
این متد برای بهینه‌سازی حافظه استفاده می‌شود و ظرفیت صف را به اندازه واقعی داده‌ها کاهش می‌دهد.
GetEnumerator
این متد امکان پیمایش صف با استفاده از حلقه‌ها و الگوهای تکرار را فراهم می‌کند

کاربردهای رایج
کلاس <Queue<T در سناریوهای متعددی کاربرد دارد؛ از جمله:
مدیریت نوبت در سیستم‌های کاربرمحور
الگوریتم‌های گراف مانند جستجوی سطحی (BFS)
صف‌های پردازش پیام در سیستم‌های توزیع‌شده
مدیریت وظایف پس‌زمینه در برنامه‌های چندنخی

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍95
آشنایی با Namespace

#csharp_for_beginners

۱. مفهوم Namespace

در سی‌شارپ، Namespace برای سازماندهی کد استفاده می‌شود و دو نقش مهم دارد:

سازمان‌دهی داخلی: تقسیم کلاس‌ها، ساختارها، رابط‌ها و… در پروژه، به گونه‌ای که ساختار واضح‌تری داشته باشند.
نمایش بیرونی: وقتی که برنامه یا کتابخانه‌ای قرار است در جایی دیگر استفاده شود، نام اعضا (types) مشخص و قابل تفکیک هستند.

۲. نحوه تعریف Namespace
با کلیدواژه namespace و سپس یک شناسه (یا مجموعه‌ای از شناسه‌ها با نقطه)
namespace MyApp.Services
{
class MyService { }
}


یا روش جدید File‑scoped از C#10
csharp

namespace MyApp.Services;

class MyService { }


۳. قوانین نام‌گذاری (Naming Guidelines)
توصیه می‌شود نام‌ها شامل <شرکت>.<محصول یا تکنولوژی>[.<ویژگی>] باشند.

از PascalCase استفاده شود و از تغییر نام‌های عمومی یا تک‌کلمه مانند Log, Message خودداری شود تا از تداخل جلوگیری شود.

۴. نکات فنی و ساختاری
فضای جهانی (global namespace) همیشه حضور دارد و انواع بدون namespace در آن تعریف می‌شوند.

توصیه می‌شود برای سازمان‌دهی فایل‌ها، هر پوشه متناظر با یک namespace باشد. استفاده از پایه فایل‌ها یک نوع استاندارد مدرن است.

۵. تو در تویی Namespace (Open Namespace )
می‌توان namespace را داخل یک namespace دیگر تعریف کرد یا در فایل‌های متعدد با یک نام مشترک تعریف‌هایی مجزا داشت و همه به هم ملحق می‌شوند.

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
5👍3🔥1
تبدیل نوع (Casting & Type Conversions) در سی‌شارپ

#csharp_for_beginners

در زبان برنامه‌نویسی سی‌شارپ، متغیرها انواع (Types) مختلفی دارند؛ مانند int، double، string و غیره. گاهی اوقات نیاز داریم مقدار یک نوع را به نوعی دیگر تبدیل کنیم. این فرآیند تبدیل نوع (Type Conversion) یا Casting نامیده می‌شود. سی‌شارپ دو نوع اصلی تبدیل دارد:

Implicit Conversion
Explicit Conversion / Casting

تبدیل ضمنی (Implicit Conversion)
در این نوع تبدیل، کامپایلر خودش به‌طور خودکار نوع را تبدیل می‌کند، چون خطر از دست رفتن داده وجود ندارد. مثلاً وقتی مقدار int را به long تبدیل می‌کنیم:

int myInt = 100;
long myLong = myInt; // تبدیل ضمنی



تبدیل صریح (Explicit Conversion / Casting)
زمانی که احتمال از بین رفتن اطلاعات وجود دارد یا کامپایلر نمی‌تواند به‌طور خودکار نوع را تبدیل کند، باید از cast صریح استفاده کنیم:

double myDouble = 123.45;
int myInt = (int)myDouble; // تبدیل صریح



استفاده از توابع Convert
سی‌شارپ کلاس System.Convert را برای تبدیل بین انواع مختلف فراهم کرده است:

string myString = "123";
int myInt = Convert.ToInt32(myString); // تبدیل رشته به عدد صحیح



استفاده از Parse و TryParse
برای تبدیل رشته به عدد (یا انواع مشابه)، می‌توان از متد Parse یا TryParse استفاده کرد:

string myString = "456";
int myInt = int.Parse(myString); // اگر رشته ناصحیح باشد، استثناء رخ می‌دهد

bool success = int.TryParse(myString, out int result);
// اگر موفق باشد، result مقدار عددی می‌گیرد، در غیر این صورت صفر می‌شود


تبدیل نوع‌های مرجع (Reference Types)
در حالت‌های پیشرفته‌تر، تبدیل نوع بین کلاس‌ها (مثلاً از یک کلاس فرزند به کلاس والد یا برعکس) هم امکان‌پذیر است:

object obj = "Hello";
string str = (string)obj; // تبدیل صریح با cast

// استفاده از 'as'
string str2 = obj as string; // اگر نشود، مقدار null برمی‌گرداند



🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍87
متغیرهای محلی با نوع ضمنی (var) در سی‌شارپ

#csharp_for_beginners

در سی‌شارپ، زمانی که متغیری را با استفاده از کلیدواژه var تعریف می‌کنید، نیازی به مشخص کردن نوع آن ندارید؛ زیرا کامپایلر نوع مناسب را از بند عبارت سمت راست تشخیص می‌دهد.
نوع ممکن است جزئی از انواع داخلی مثل int یا string باشد، یا حتی انواع ناشناس (anonymous types) یا انواع تعریف‌شده توسط کاربر یا کتابخانه‌های دات‌نت.

نمونه‌های کاربردی

مثال‌هایی از تعریف متغیرهای ضمنی با var:

var i = 5;                     // نوع int
var s = "Hello"; // نوع string
var a = new[] { 0, 1, 2 }; // نوع int[]
var expr = from c in customers where c.City == "London" select c; // IEnumerable<Customer> یا IQueryable<Customer>
var anon = new { Name = "Terry", Age = 34 }; // نوع ناشناس
var list = new List<int>(); // List<int>


محدودیت‌ها و قوانین استفاده

-ابتدا باید مقداردهی شود: var فقط در صورتی کاربرد دارد که متغیر در همان خط تعریف، مقداردهی شده باشد. تعریف بدون مقدار (var x;) یا مقداردهی به null، باعث خطا می‌شود.
-قابل استفاده فقط در سطح محلی: نمی‌توان از var برای تعریف فیلدهای سطح کلاس، پارامترهای متد یا نوع بازگشتی متد استفاده کرد.
تعریف همزمان چند متغیر با var امکان‌پذیر نیست، نظیر: var a = 1, b = 2; باعث خطا می‌شود.
-نوع متغیر در طول زمان تغییر نمی‌کند: نوعی که کامپایلر تشخیص می‌دهد ثابت است.

کاربرد در LINQ و انواع ناشناس

در بسیاری از موارد استفاده از var اختیاری است؛ اما زمانی که نوع ناشناس به‌کار رفته، استفاده از var الزامی است، زیرا نوع ناشناس نام مشخصی ندارد:

var studentQuery = from student in students
where student.FirstName[0] == firstLetter
select new { student.FirstName, student.LastName };

foreach (var anonType in studentQuery)
{
Console.WriteLine($"First = {anonType.FirstName}, Last = {anonType.LastName}");
}


بدون var، امکان دسترسی به خواص این نوع‌ها وجود ندارد.

چه زمانی بهتر است یا بهتر نیست از var استفاده شود؟

استفاده از var خوانایی کد را بیشتر می‌کند، به‌ویژه در مواردی که نوع پیچیده‌ای پشت مقدار است (مثلاً Dictionary<string, List<int>>).
در اسناد رسمی مایکروسافت توصیه می‌شود از var فقط زمانی استفاده کنید که نوع از مقدار سمت راست به‌وضوح مشخص باشد. یعنی اگر از خواننده انتظار دارید نوع را تشخیص دهد، فقط در آن صورت از var استفاده کنید.
یکی از ابزارهای IDE (مثل Visual Studio) امکان تبدیل var به نوع صریح (explicit type) را برای خوانایی بیشتر فراهم کرده است؛ البته در شرایطی که مقدار در همان خط تعریف نشده یا نوع ناشناس نیست.

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍72🔥2
آشنایی باScope of Variables در سی‌شارپ

#csharp_for_beginners

در سی‌شارپ Scope به معنای محدوده‌ای است که یک متغیر در برنامه قابل دسترسی بوده و قابل استفاده است. در زبان سی‌شارپ، محدوده‌ی تغییرپذیری متغیرها معمولاً به سه سطح اصلی تقسیم می‌شود: در سطح کلاس (Class-Level Scope)، در سطح متد (Method-Level Scope)، و در سطح بلوک (Block-Level Scope)

۱. سطح کلاس Class-Level Scope

متغیرهایی که در داخل کلاس اما بیرون از تمامی متدها تعریف می‌شوند، دارای محدوده‌ی سطح کلاس هستند و به‌عنوان field یا اعضای کلاس شناخته می‌شوند. این متغیرها در تمامی متدها و بلوک‌های همان کلاس قابل دسترسی‌اند—مگر دسترسی‌ آن‌ها توسط Access Modifier محدود شده باشد، اما داخل همان کلاس تأثیری بر دسترسی ندارد.
مثال:

class Geeks {
int a = 10; // کلاس-سطح
public void Display() {
Console.WriteLine(a); // قابل دسترسی
}
}


۲. سطح متد Method-Level Scope

متغیرهایی که در داخل یک متد تعریف می‌شوند، محدوده‌ی سطح متد دارند و به‌عنوان local variables شناخته می‌شوند. این متغیرها فقط در همان متد قابل دسترسی‌اند. همچنین امکان تعریف دو متغیر با نام یکسان در یک محدوده وجود ندارد و دسترسی به آن‌ها پس از خاتمه‌ی اجرای متد ممکن نیست.

۳. سطح بلوک Block-Level Scope

متغیرهایی که در داخل یک بلوک مانند if، for، { ... } یا دیگر ساختارهای کنترلی تعریف شوند، محدوده‌ی بلوکی دارند. یعنی تنها در همان بلوک (یا بلوک‌های تو در تو) قابل استفاده‌اند و خارج از آن بلوک قابل دسترسی نیستند.

مثال:
for (int i = 0; i < 5; i++) {
Console.WriteLine(i);
}
// Console.WriteLine(i); // خطا—خارج از بلوک for


نکته‌: Shadowing در سی‌شارپ

در بسیاری از زبان‌ها، متغیرهایی که در داخل بلوک داخلی تعریف می‌شوند می‌توانند متغیرهای بیرونی با همان نام را مخفی یا Shadow کنند. اما در سی‌شارپ، shadowing نام متغیرها بین بلوک شرطی (if) و متد مجاز نیست—اگرچه بین کلاس و متد یا بین کلاس‌ها ممکن است.

قواعد Scope در سی‌شارپ:

۱ .ساختاریافته‌تر و خواناتر باشند.
۲. از خطاهایی مانند استفاده از متغیر خارج از محدوده جلوگیری شود.
۳. حافظه بهینه‌تر مدیریت گردد، چرا که متغیرهای محلی پس از انجام وظیفه آزاد می‌شوند.

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍7
معرفی کلی Pattern Matching در زبان سی‌شارپ

#csharp_for_beginners

تکنیک Pattern matching روشی است که امکان بررسی یک عبارت (expression) براساس ویژگی‌های خاصی را فراهم می‌کند.
این روش در سی‌شارپ کمک می‌کند تا کدها خواناتر، مختصرتر و ایمن‌تر شوند، مثلاً به جای عملیات مرسوم قبلی، بررسی نوع یا وضعیت ارزش‌ها را در قالب‌هایی مستقیم‌تر انجام می‌دهد.


سازوکارها و ساختارهای اصلی در سی‌شارپ

۱. is Expression (عمل‌گر is)

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

مثال

int? maybe = 12;
if (maybe is int number) {
Console.WriteLine($"The value is {number}");
}


۲. عبارت switch یا switch Expression

یک روش کامپکت برای انتخاب رفتار یا مقدار خروجی بر اساس الگوی تطابق

visitorCount switch {
1 => 12.0m,
2 => 20.0m,
_ => 0.0m
}


Declaration & Type Patterns
Constant Patterns
Relational Patterns
Property Patterns
Positional Patterns
Var Patterns
Discard Pattern (_)
Logical Patterns (and, or, not)
List Patterns

مثال کاربردی ساده (Switch Expression)

برای تفهیم بهتر، یک مثال ساده از switch expression

var x = 4;
string result = x switch {
1 => "one",
2 => "two",
3 => "three",
_ => "other"
};
Console.WriteLine(result); // خروجی: "other"


نکات مهم و پیش‌فرض‌ها
خوانایی و اجتناب از boilerplate: الگوها کمک می‌کنند تا از ساختارهای طولانی if-else یا casting‌های دستی دوری کنیم.

اعتبارسنجی compile-time: کامپایلر در صورت نپرداختن به حالت‌هایی مانند null یا همهٔ مقدارهای احتمالاً ممکن، هشدار می‌دهد.

ترکیب با refactoring‌های IDE: ابزار‌هایی مانند Visual Studio پیشنهاد می‌دهند به جای as و null check، از pattern matching استفاده شود.

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
7👍4
گاهی وقت‌ها لازم است مرورگر به‌صورت خودکار اجرا شود و بخشی از کارها را انجام دهد.

مثال:
- نوشتن تست E2E برای نرم‌افزار: باز کردن سایت، لاگین، بررسی مودال‌ها
- گرفتن PDF یا اسکرین‌شات از صفحات خاص
- اسکرپینگ داده‌ها از سایت‌های مختلف

برای این کارها، سه ابزار محبوب داریم:
ابزار Selenium: قدیمی‌ترین و پایدارترین ابزار تست مرورگرها. پشتیبانی از همه مرورگرها، سازگار با زبان‌های مختلف (Java, Python, C#, ...)، سرعت پایین‌تر.
نکته: Dockerize کردن آن گاهی دردسر دارد، بخصوص در CI/CD.

ابزار :Puppeteer / PuppeteerSharp: ابزاری مدرن مبتنی بر DevTools، مخصوص Chrome/Chromium، سریع و سبک، مناسب برای اسکرپینگ، تولید PDF، گرفتن اسکرین‌شات.
نکته: نسخه‌ی #CSharp با نام PuppeteerSharp در NuGet موجود است و راحت در محیط‌های Docker قابل استفاده ولی محدود به مرورگرهای گوگل!


ابزار Playwright: نسل جدید از مایکروسافت، با قابلیت‌های پیشرفته، پشتیبانی از Chrome, Firefox, Safari (WebKit) ،Auto-wait هوشمند، کانتکست‌های ایزوله، پشتیبانی رسمی از #CSharp، Node.js، Python، Java، مناسب برای تست‌های مدرن و پروژه‌های جدید، عالی برای شبیه‌سازی چند کاربر همزمان.

پیشنهاد من:
پروژه‌ی جدید و کراس‌مرورگر از Playwright

اسکرپینگ سبک یا تولید PDF فقط روی کروم از Puppeteer / PuppeteerSharp

پروژه‌ی Enterprise یا نیاز به سازگاری Legacy از Selenium

▫️اگه تجربه‌ای با این ابزارها دارید یا سوالی براتون پیش اومده، خوشحال می‌شم بشنوم.

🔗 مطلب کامل را در اینجا بخوانید.

#حامد_حاجیلو (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

______
👍93🔥1
کانستراکترها (سازنده‌ها) در سی‌شارپ

#csharp_for_beginners

۱. تعریف و نقش
کانستراکتر روش (متودی) است که توسط محیط زمان اجرای (Runtime) هنگام ساخت یک شیء (instance) از یک کلاس یا ساختار (struct) فراخوانی می‌شود. می‌توان برای یک کلاس یا struct چندین کانستراکتر با پارامترهای مختلف تعریف کرد تا اطمینان حاصل شود که اشیاء جدید در وضعیت معتبر ساخته می‌شوند.

۲. ترتیب اجرای مراحل ساخت شیء
هنگام ساخت یک شیء با عملگر new، مراحل زیر به ترتیب انجام می‌شوند:
۱. میدان‌های نمونه‌ای (instance fields) به مقدار پیش‌فرض (مثل صفر) مقداردهی می‌شوند.
۲. مقداردهی اولیه‌ی فیلدها (field initializers) در نوع مشتق‌شده اجرا می‌شود.
۳. مقداردهی اولیه‌ی فیلدها در نوع پایه آغاز می‌شود تا به System.Object برسد.
۴. کانستراکترهای نمونه‌ای کلاس‌های پایه ابتدا اجرا می‌شوند تا به کلاس جاری برسند.
۵. در نهایت، کانستراکتر خود کلاس اجرا می‌شود.
۶. اگر از initializerهای شیء (object initializers) استفاده شده باشد، آن‌ها بعد از کانستراکتر اجرا می‌شوند، به ترتیب متنی ظاهرشده.

در ساختارها (struct) اگر از مقدار پیش‌فرض (default) استفاده شود، همه فیلدها به صفر مقداردهی می‌شوند.
در آرایه‌ها هم تمامی عناصر هنگام ساخت آرایه به مقدار پیش‌فرضشان (صفر یا null) تنظیم می‌شوند.

۳. کانستراکترهای استاتیک (static constructors)
کانستراکتر استاتیک (بدون پارامتر) برای مقداردهی اولیه‌ی اعضای استاتیک استفاده می‌شود.
این کانستراکتر حداکثر یک‌بار، پیش از هر کانستراکتر نمونه‌ای اجرا می‌شود.
در صورت عدم تعریف آن، کامپایلر به‌طور خودکار اعضای استاتیک را به مقادیر پیش‌فرضشان مقداردهی می‌کند.

نمونه کانستراکتر:

public class Person
{
private string last, first;

public Person(string lastName, string firstName)
{
last = lastName;
first = firstName;
}
}


۴. کانستراکتر اولیه (Primary constructor)
از سی‌شارپ ۱۴ به بعد امکان تعریف primary constructor وجود دارد: روشی برای مشخص کردن پارامترهایی که برای نمونه‌سازی نوع مورد نیاز هستند.
• مثال:

public class LabelledContainer<T>(string label)
{
public string Label { get; } = label;
public required T Contents { get; init; }
}
. می‌توان برای یک کلاس یا struct چندین کانستراکتر با پارامترهای مختلف تعریف کرد تا اطمینان حاصل شود که اشیاء جدید در وضعیت معتبر ساخته می‌شوند


ترتیب اجرا
۵. کانستراکترهای partial
از سی‌شارپ ۱۴ به بعد امکان تعریف کانستراکترهای partial در انواع جزئی وجود دارد.
این کانستراکترها باید دارای اعلامیه (declaration) و پیاده‌سازی (implementation) با امضای (signature) یکسان باشند.

همچنین ()base : یا ()this : نمی‌تواند در بخش declaration استفاده شود؛ این موارد باید در implementing declaration قرار بگیرند.

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍10
ایندکسر (Indexer) در سی‌شارپ

#csharp_for_beginners

وقتی یک کلاس یا ساختار (struct) را می‌سازیم، ممکن است بخواهیم از آن مانند آرایه‌ای با “[]” به موقعیت‌های کلاس یا ساختار دسترسی داشت: هم خواندن و هم نوشتن. ایندکسرها این امکان را فراهم می‌کنند. یعنی به جای روش‌های معمول مثل GetItem(…) یا SetItem(…)، بتوان نوشت:
myObject[i] = value;
var x = myObject[i];

ساختار ایندکسر

ایندکسر شبیه پراپرتی تعریف می‌شود، با این تفاوت که زمان get و set یک یا چند پارامتر (معمولاً اندیس) دریافت می‌کند. برای تعریف ایندکسر از کلمه‌ی کلیدی this استفاده می‌کنیم:
public class SampleCollection<T>
{
private T[] arr = new T[100];

public T this[int i]
{
get { return arr[i]; }
set { arr[i] = value; }
}

انواع ایندکسر
خواندنی و نوشتنی (Read/Write): هم get و هم set را داراست.
فقط خواندنی (Read-only): فقط get را داراست. مثلاً اگر لازم باشد فقط به داده‌ها دسترسی دهیم ولی تغییری در داده‌ها ندهیم.
چند پارامتری: ایندکسر می‌تواند بیشتر از یک ایندکس داشته باشد، مانند ایندکسر دو بعدی
غیر عددی: الزامی نیست شاخص‌ها عدد باشند؛ می‌اتونند نوعی مانند رشته، تاریخ یا هر نوع دلخواهی باشند.

موارد استفاده
شبیه‌سازی آرایه یا لیست: وقتی کلاس شما مانند یک مجموعه عمل می‌کند، ولی نمی‌خواهید جزئیات داخلی را بیرون دهید.
دیکشنری / نگاشت (mapping): مثلاً وقتی می‌خواهید بر اساس کلید (مانند رشته یا تاریخ) مقدار دهی کنید یا مقداری را بگیرید، بجای متدهایی مانند Get یا Find، می‌توانید بنویسید: obj[“key”] .
داده‌های وابسته به زمان یا تاریخ: مانند ثبت دما بر اساس تاریخ، طوری که بتوانید با obj[date] بخوانید یا بنویسید.
زمانی که نمی‌خواهیم کل داده‌ها به صورت همزمان در حافظه داشته باشیم: ممکن است بخش‌هایی از داده را بر حسب نیاز بارگذاری یا حذف کنید. ایندکسر اجازه می‌دهد که فقط وقتی به داده‌ای نیاز داریم، آن قسمت پردازش شود.

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍43
اجرای کدهای پایتون در دات‌نت با جادوی CSnakes!

اگر امکان اجرای کدهای پایتون در همان پروسس دات‌نت وجود داشته باشد، یعنی تمام ۱.۵ میلیون مدل هوش مصنوعی که تا به حال روی HuggingFace قرار گرفته را می‌توان با همان پرفورمنس و بدون نیاز به کشیدن لایه‌های REST در دسترس داشت.

پروژه CSnakes در واقع یک Source Generator و Runtime برای سی‌شارپ است که با بهره‌گیری از Python C-API امکان تولید خودکار کلاس‌های دات‌نت از اسکریپت‌های پایتون رو فراهم می‌کنه. شما فقط کافیه پکیج CSnakes.Runtime رو از NuGet نصب کنید و اسکریپت‌های پایتون‌تون رو به پروژه اضافه کنید تا بدون کوچک‌ترین overhead یا لایه اضافی، هر تابع پایتون به‌صورت یک متد native سی‌شارپ قابل فراخوانی باشد. این رویکرد، سرعت و مقیاس‌پذیری Enterprise دات‌نت را با انعطاف‌پذیری و اکوسیستم غنی پایتون پیوند می‌زند و توسعه اپلیکیشن‌های هوش‌مصنوعی و Data Science را به سطحی جدید می‌رساند.

کل‌کل‌هایی هم که این دونفر سر زبان‌های سی‌شارپ و پایتون می‌کنن خیلی با مزه‌س!

🔗 در این ویدئو Scott Hanselman و Anthony Shaw پروژه CSnakes را معرفی می‌کنند. پیشنهاد می‌کنم حتما این ویدئوی جذاب را ببینید.


#csharp #python #machine_learning

#مهران_داودی (لینکدین - بلاگ)

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍109🔥2👏1😱1
رابط (Interface) در سی‌شارپ

#csharp_for_beginners

تعریف و کاربرد
کلمه کلیدی interface برای تعریف یک قرارداد به کار می‌رود. این قرارداد مجموعه‌ای از امضاهای اعضا را مشخص می‌کند که می‌تواند شامل متدها، ویژگی‌ها، ایندکسرها، رویدادها و غیره باشد.
یک interface می‌تواند اعضایی بدون پیاده‌سازی یا اعضایی با پیاده‌سازی پیش‌فرض داشته باشد. همچنین امکان تعریف اعضای static نیز وجود دارد.

از نسخه سی‌شارپ ۱۱ به بعد interface می‌تواند اعضای static abstract یا static virtual داشته باشد. این موضوع زمانی مفید است که بخواهیم در یک نوع عمومی (generic) رفتار مشخصی برای تمام انواع پیاده‌ساز اجباری کنیم. به عنوان مثال در کتابخانه دات‌نت انواع عددی مختلف واسط INumber را پیاده می‌کنند تا عملیات ریاضی مشترک میان آنها تضمین شود.

قوانین دسترسی و سطح تعریف
یک interface سطح بالا (در فضای نام) می‌تواند internal یا public باشد. پیش‌فرض internal است.
اگر interface به صورت تو در تو داخل یک نوع دیگر تعریف شود می‌توان از هر نوع اصلاح‌کننده دسترسی استفاده کرد.
اعضای interface که بدون پیاده‌سازی هستند اصلاح‌کننده دسترسی ندارند. اما اگر برای آن عضو پیاده‌سازی پیش‌فرض بنویسیم می‌توان دسترسی آن را مشخص کرد.


انواع اعضا در interface
یک interface می‌تواند شامل موارد زیر باشد:
-متدها
-ویژگی‌ها
-ایندکسرها
-رویدادها
-ثابت‌ها
-عملگرها
-انواع تو در تو
-سازنده ایستا

پیاده‌سازی
یک interface می‌تواند از یک یا چند interface دیگر مشتق شود. هر نوعی که interface مشتق را پیاده کند باید تمام اعضای interfaceهای پایه و مشتق را پیاده‌سازی کند.
کلاس یا ساختار می‌تواند اعضای interface را به صورت ضمنی یا به صورت صریح (explicit implementation) پیاده کند.
اگر یک عضو interface پیاده‌سازی پیش‌فرض داشته باشد معمولاً تنها از طریق نمونه‌ای از نوع interface قابل دسترسی است نه مستقیماً از طریق کلاس پیاده‌ساز.

مثال‌ها

تعریف یک قرارداد ساده

interface ISampleInterface
{
void SampleMethod();
}

class ImplementationClass : ISampleInterface
{
void ISampleInterface.SampleMethod()
{
// پیاده‌سازی متد
}
}


تعریف ویژگی‌ها و متدها

interface IPoint
{
int X { get; set; }
int Y { get; set; }
double Distance { get; }
}

class Point : IPoint
{
public int X { get; set; }
public int Y { get; set; }
public double Distance => Math.Sqrt(X * X + Y * Y);
}



🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍2
اپراتورها در سی‌شارپ

#csharp_for_beginners

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

دسته‌های اصلی اپراتورها
۱. اپراتورهای حسابی: برای انجام محاسبات ریاضی مثل جمع، تفریق، ضرب، تقسیم و باقی‌مانده استفاده می‌شوند.
۲. اپراتورهای مقایسه‌ای: برای مقایسه دو مقدار به‌کار می‌روند، مثل بزرگ‌تر، کوچک‌تر یا برابر بودن.
۳. اپراتورهای منطقی بولی: برای ترکیب و معکوس کردن مقادیر درست و نادرست (true/false) استفاده می‌شوند.
۴. اپراتورهای بیت‌به‌بیت و شیفت: برای کار روی بیت‌های داخلی داده‌های عددی کاربرد دارند.
۵. اپراتورهای برابری: برای بررسی مساوی یا نامساوی بودن دو مقدار استفاده می‌شوند.
۶. اپراتورهای انتساب و ترکیبی: برای مقداردهی متغیرها یا ترکیب یک عملیات با انتساب به‌کار می‌روند، مانند += یا -=.
۷. اپراتور شرطی سه‌تایی: یک عبارت شرطی است که بین دو مقدار یکی را انتخاب می‌کند.
۸. اپراتورهای Null: برای بررسی نال بودن و جایگزین کردن مقدار پیش‌فرض استفاده می‌شوند.
۹. اپراتورهای دسترسی به عضو، ایندکس، افزایش یا کاهش و تبدیل نوع: برای دسترسی به اعضای یک شیء، کار با آرایه‌ها، افزایش/کاهش مقدار یا تبدیل نوع داده به نوع دیگر استفاده می‌شوند.

اولویت و جهت اجرای اپراتورها
اپراتورها در سی‌شارپ اولویت‌های مختلفی دارند. اپراتورهایی با اولویت بالاتر زودتر اجرا می‌شوند. اگر چند اپراتور در یک سطح اولویت باشند، ترتیب اجرا توسط جهت ارجاع مشخص می‌شود. اکثر اپراتورهای دوتایی از چپ به راست اجرا می‌شوند، اما برخی مانند انتساب و اپراتور شرطی از راست به چپ اجرا می‌شوند.
به‌عنوان مثال، عبارت a + b - c به‌صورت (a + b) - c محاسبه می‌شود، ولی عبارت x = y = z به شکل x = (y = z) ارزیابی خواهد شد

ترتیب ارزیابی عملوندها
به‌طور پیش‌فرض، عملوندهای یک اپراتور از چپ به راست محاسبه می‌شوند. با این حال، برخی اپراتورها شرطی هستند و ممکن است همه عملوندها محاسبه نشوند.
• در اپراتور && اگر عملوند سمت چپ برابر false باشد، سمت راست دیگر بررسی نمی‌شود.
• در اپراتور || اگر عملوند سمت چپ true باشد، سمت راست اجرا نمی‌شود.
• در اپراتور ?? یا ??=، اگر مقدار سمت چپ نال نباشد، سمت راست محاسبه نمی‌شود.
• در اپراتور شرطی سه‌تایی ?: فقط یکی از شاخه‌ها اجرا می‌شود.
• در عملگرهای شرطی نال مانند ?. یا ?[]، اگر شیء سمت چپ نال باشد، ادامه‌ی عبارت متوقف می‌شود

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍81🔥1
ساختارها در سی‌شارپ

#csharp_for_beginners

ساختار یا struct نوعی value type در زبان سی‌شارپ است که برای نگهداری داده‌ها و رفتار مرتبط با آن‌ها استفاده می‌شود.
وقتی متغیری از نوع struct ساخته می‌شود، داده‌ها مستقیماً درون آن متغیر ذخیره می‌شوند، نه در یک شیء جداگانه در heap.
در نتیجه، وقتی یک struct به متد ارسال یا از متد بازگردانده می‌شود، کل مقدار آن کپی می‌گردد.
به همین دلیل، struct برای انواع داده‌ای کوچک و مستقل مناسب است.
در مقابل، اگر نوعی داده رفتار پیچیده یا اندازه‌ی بزرگ دارد، معمولاً کلاس گزینه‌ی بهتری است.

مثال ساده از تعریف ساختار

public struct Coords
{
public Coords(double x, double y)
{
X = x
Y = y
}

public double X { get }
public double Y { get }

public override string ToString() => $"({X}, {Y})"
}



یک نوع دیگر به نام readonly struct & readonly

می‌توان یک ساختار را با کلیدواژه readonly تعریف کرد تا تغییرناپذیر باشد.
در یک readonly struct تمام فیلدها باید readonly باشند و تمام ویژگی‌ها (properties) باید فقط getter داشته باشند یا از نوع init باشند. در این حالت ساختار دیگر قابل تغییر نیست و اطمینان حاصل می‌شود که داده‌ها پس از ساخت ثابت باقی می‌مانند.

همچنین می‌توان متدهای خاصی را با کلیدواژه readonly مشخص کرد تا نشان دهد که این متدها وضعیت ساختار را تغییر نمی‌دهند. اگر چنین متدی درون ساختار فراخوانی شود، کامپایلر از تغییر وضعیت جلوگیری می‌کند و در صورت نیاز، یک کپی موقت از ساختار ایجاد می‌کند.

مثال از readonly struct

public readonly struct Coords
{
public Coords(double x, double y)
{
X = x
Y = y
}

public double X { get; init; }
public double Y { get; init; }

public readonly override string ToString() => $"({X}, {Y})"
}


آرایه‌های درون‌خطی (inline arrays)

از نسخه‌ی سی‌شارپ ۱۲ به بعد، امکان تعریف آرایه‌های درون‌خطی در قالب struct فراهم شده است. در این نوع ساختار، فقط یک فیلد داخلی وجود دارد که شامل یک بلوک پیوسته از عناصر داده است. این ویژگی برای موقعیت‌هایی که نیاز به سرعت بالا و دسترسی سریع به حافظه وجود دارد مفید است.

مقداردهی اولیه و مقدار پیش‌فرض struct

ساختارها مستقیماً داده‌ها را درون خود ذخیره می‌کنند. هنگامی که از دستور default برای ساختار استفاده شود، همه‌ی فیلدها با مقدار پیش‌فرض خود مقداردهی می‌شوند و هیچ سازنده‌ای فراخوانی نمی‌شود.

اگر برای ساختار سازنده‌ی بدون پارامتر تعریف شود، باز هم دستور default آن را فراخوانی نمی‌کند و مقدار پیش‌فرض برای هر فیلد اعمال می‌شود.
از سی‌شارپ ۱۱ به بعد اگر سازنده مقداری برای فیلدها تعیین نکند، کامپایلر به صورت خودکار آن‌ها را با مقدار پیش‌فرض مقداردهی می‌کند.

همچنین می‌توان بدون استفاده از new یک متغیر از نوع ساختار تعریف کرد، اما در این صورت تمام فیلدهای آن باید پیش از استفاده مقداردهی شوند.



🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍4
تعریف Enum

#csharp_for_beginners

یک Enum در واقع نوع داده‌ای سفارشی است که مجموعه‌ای از ثابت‌های عددی نام‌گذاری‌شده را در خود نگه می‌دارد. برای مثال:

enum Season
{
Spring,
Summer,
Autumn,
Winter
}


در اینجا، اعضا به ترتیب دارای مقادیر عددی 0، 1، 2 و 3 هستند. نوع پایه‌ی Enum به‌صورت پیش‌فرض int است، اما می‌توان آن را تغییر داد.

تعیین نوع پایه و مقادیر صریح


می‌توان نوع پایه و مقادیر اعضا را به‌صورت دستی مشخص کرد:

enum ErrorCode : ushort
{
None = 0,
Unknown = 1,
ConnectionLost = 100,
OutlierReading = 200
}


در این مثال، نوع پایه ushort است و هر عضو مقدار خاص خود را دارد.

نکات مهم در استفاده از Enum
مقدار پیش‌فرض یک Enum برابر با عدد صفر است، حتی اگر هیچ عضوی با مقدار صفر تعریف نشده باشد.

تبدیل عددی به Enum مجاز است، اما اگر مقدار عددی به هیچ عضو مشخصی مربوط نباشد، نتیجه ممکن است نامعتبر باشد.

کاربردهای Enum

۱. انتخاب از میان چند مقدار مشخص
یک Enum زمانی مفید است که بخواهیم متغیری یکی از چند مقدار مشخص را بگیرد. مثلاً برای وضعیت سفارش یا فصل سال:

enum OrderStatus
{
Pending,
Processing,
Shipped,
Delivered
}


۲. استفاده به‌صورت ترکیبی (Flags)
گاهی لازم است چند مقدار با هم ترکیب شوند. در این حالت از ویژگی [Flags] استفاده می‌کنیم و مقادیر را به‌صورت توان‌های دو تعریف می‌کنیم:

[Flags]
public enum Days
{
None = 0,
Monday = 1,
Tuesday = 2,
Wednesday = 4,
Thursday = 8,
Friday = 16,
Saturday = 32,
Sunday = 64,
Weekend = Saturday | Sunday
}



جمع‌بندی
ابزار Enum یکی از ابزارهای ساده اما قدرتمند در سی‌شارپ است که به شما کمک می‌کند مجموعه‌ای از مقادیر ثابت را با نام‌های قابل فهم تعریف کنید. این کار باعث افزایش خوانایی، کاهش خطا و بهبود نگهداری کد می‌شود. با رعایت چند قاعده‌ی ساده —مثل داشتن عضو صفر، اعتبارسنجی مقادیر و استفاده‌ی درست از [Flags]— می‌توان Enumهایی ساخت که در پروژه‌های واقعی بسیار کاربردی و ایمن باشند.

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍92
کلاس لیست (List)

#csharp_for_beginners

کلاس «لیست» یا List در فضای نام System.Collections.Generic قرار دارد و یکی از پرکاربردترین ساختارهای داده در چارچوب ‎.NET است. این کلاس نمایان‌گر مجموعه‌ای از عناصر هم‌نوع (دارای نوع مشخص) است که می‌توان به هر کدام از آن‌ها از طریق شماره‌ی ایندکس دسترسی داشت.
علاوه بر این، کلاس لیست امکاناتی برای افزودن، حذف، جستجو، مرتب‌سازی و مدیریت داده‌ها در اختیار برنامه‌نویس قرار می‌دهد.

پارامتر نوع
لیست از نوع عمومی (Generic) است و دارای پارامتری به نام T می‌باشد.
این پارامتر مشخص می‌کند که نوع داده‌ای که قرار است در لیست نگهداری شود چیست (مثلاً عدد صحیح، رشته، شیء و غیره).

سازنده‌ها (ایجادکننده‌های لیست)
کلاس لیست چند روش برای ساخت شیء جدید ارائه می‌دهد:
سازنده‌ی بدون ورودی: یک لیست خالی با ظرفیت اولیه‌ی پیش‌فرض می‌سازد.
سازنده‌ای که ورودی آن یک مجموعه است: از عناصر مجموعه‌ی داده شده، یک لیست جدید می‌سازد.
سازنده‌ای که عدد صحیح می‌گیرد: لیستی خالی با ظرفیت اولیه‌ی مشخص‌شده ایجاد می‌کند.

ویژگی‌های اصلی لیست
ظرفیت (Capacity): تعداد کل عناصری که لیست می‌تواند بدون تغییر اندازه در خود جای دهد.
تعداد (Count): تعداد واقعی عناصری که در حال حاضر در لیست وجود دارند.
اندیس (Item): اجازه می‌دهد تا با استفاده از شماره‌ی اندیس، به یک عنصر دسترسی پیدا کرده یا مقدار آن را تغییر دهیم.

متدهای مهم در لیست
کلاس لیست دارای ده‌ها متد کاربردی است. در ادامه مهم‌ترین آن‌ها آورده شده است

افزودن (Add): یک عنصر جدید را به انتهای لیست اضافه می‌کند.
افزودن مجموعه‌ای از عناصر (AddRange): چندین عنصر را به انتهای لیست اضافه می‌کند.
فقط‌خواندنی (AsReadOnly): نمایی فقط برای خواندن از لیست ایجاد می‌کند که قابل تغییر نیست.
جستجوی دودویی (BinarySearch): با استفاده از الگوریتم جستجوی دودویی، عنصری را در لیست مرتب‌شده پیدا می‌کند.
پاک‌کردن (Clear): همه‌ی عناصر موجود در لیست را حذف می‌کند.
شامل بودن (Contains): بررسی می‌کند که آیا یک عنصر خاص در لیست وجود دارد یا نه.
کپی کردن (CopyTo): عناصر لیست را در آرایه‌ای دیگر کپی می‌کند.
افزایش ظرفیت (EnsureCapacity): اطمینان حاصل می‌کند که ظرفیت لیست به اندازه‌ی کافی برای اضافه شدن عناصر جدید وجود دارد.
وجود شرطی (Exists): بررسی می‌کند آیا عنصری مطابق یک شرط مشخص در لیست وجود دارد یا نه.
یافتن اولین مورد (Find): اولین عنصری که با شرط داده‌شده مطابقت دارد را برمی‌گرداند.
یافتن همه‌ی موارد (FindAll): تمام عناصری که شرط را برآورده می‌کنند بازمی‌گرداند.
یافتن اندیس (FindIndex / FindLastIndex): موقعیت اولین یا آخرین عنصر مطابق شرط را برمی‌گرداند.
برای هر عنصر (ForEach): عملی را روی تمام عناصر اجرا می‌کند.
دریافت بازه (GetRange): بخش مشخصی از لیست را به‌صورت یک لیست جدید برمی‌گرداند.
درج (Insert / InsertRange): عنصری یا مجموعه‌ای از عناصر را در موقعیت مشخصی از لیست قرار می‌دهد.
حذف (Remove): اولین وقوع یک عنصر مشخص را حذف می‌کند.
حذف شرطی (RemoveAll): همه‌ی عناصری که شرط خاصی را برآورده می‌کنند حذف می‌کند.
حذف بر اساس اندیس (RemoveAt / RemoveRange): عنصری در یک موقعیت یا بازه‌ای از عناصر را حذف می‌کند.
معکوس‌کردن (Reverse): ترتیب عناصر را برعکس می‌کند، می‌تواند کل لیست یا بخشی از آن باشد.
مرتب‌سازی (Sort): عناصر را به ترتیب صعودی یا بر اساس مقایسه‌کننده‌ی دلخواه مرتب می‌کند.
تبدیل به آرایه (ToArray): عناصر لیست را در قالب یک آرایه بازمی‌گرداند.
بهینه‌سازی حافظه (TrimExcess): ظرفیت لیست را به تعداد واقعی عناصر کاهش می‌دهد تا از مصرف بی‌مورد حافظه جلوگیری شود.
بررسی شرط برای همه (TrueForAll): بررسی می‌کند آیا همه‌ی عناصر شرط مشخصی را برآورده می‌کنند یا خیر.

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
5👍1
تاپل‌ها در سی‌شارپ

#csharp_for_beginners

در زبان برنامه‌نویسی سی‌شارپ، از نسخه‌های جدید‌تر مفهومی با نام تاپل‌ها معرفی شده است؛ این امکان فراهم می‌کند که چند مقدار مرتبط را به‌صورت کم‌حجم و منسجم در کنار هم نگه‌دارید. به‌طور خاص، این مقاله به نوع داده‌ای به نام «تاپل مقدار» (value-tuple) می‌پردازد که در سند رسمی مایکروسافت تحت عنوان «Tuple types (C# reference)» معرفی شده است.

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

(double, int) t1 = (4.5, 3);
Console.WriteLine($"Tuple with elements {t1.Item1} and {t1.Item2}.");


برابری (Tuple equality)ها چگونه مقایسه می‌شوند

تاپل‌ها از عملگرهای == و != پشتیبانی می‌کنند؛ این مقایسه اعضای متناظر (به ترتیب) را با اپراتور مقایسه انجام می‌دهد. نام فیلدها در مقایسه دخیل نیستند؛ به همین دلیل دو تاپل با نام‌های متفاوت اما همان ترتیب و مقادیر، برابر در نظر گرفته می‌شوند.

مثال صفحه

(int a, byte b) left = (5, 10);
(long a, int b) right = (5, 10);
Console.WriteLine(left == right); // True


نام‌گذاری فیلدهای تاپل (Tuple field names)، جزئیات مهم

نحوهٔ تعیین نام فیلدها
نام فیلدها را می‌توان صریحاً هنگام مقداردهی یا در تعریف نوع تاپل مشخص کرد:

var t = (Sum: 4.5, Count: 3);
Console.WriteLine($"Sum of {t.Count} elements is {t.Sum}.");

یا:

(double Sum, int Count) d = (4.5, 3);


تاپل‌های زبان بر پایهٔ System.ValueTuple هستند؛ یعنی نوع مقدار (value type) و اعضای آن به‌صورت فیلدهای عمومی پیاده‌سازی شده‌اند. نتیجهٔ مستقیم این پیاده‌سازی این است که تاپل‌ها mutable value types هستند، یعنی می‌توان مقادیر فیلدهای‌شان را تغییر داد.

🔗 مطلب کامل را در این لینک می‌توانید مطالعه کنید.

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

کانال تلگرام:
@SoftwarePhilosophy

______
👍4