Software Philosophy – Telegram
Software Philosophy
3.45K subscribers
160 photos
41 videos
1.54K links
چکیده‌ای از مفاهیم به روز مهندسی نرم افزار برای مهندسین نرم‌افزار.
معماری نوین نرم‌افزار، تکنولوژی‌های برنامه نویسی جدید
Download Telegram
معرفی کلاس <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
Forwarded from TondTech (مسعود بیگی)
دوستان خوب و عزیزم سلام، من و تیم خوبم در #رسمیو، مدتی رو سرمون خلوت خواهد بود و دوست داریم به شکل مشاوره یا همکاری در انجام پروژه های شما (به صورت صفر تا صد یا مشارکت در پیاده سازی بخشی از سرویس هاتون) همراه باشیم .

ما توی تیممون به جز توسعه دهندگان .net و React ، پروداکت منیجر و دیزاینر هم داریم اگر لازم داشته باشید برای این پروژه ها.

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


بعد از پایان پروژه هم، پروژه رو به تیم تون تحویل میدیم و اگر نیاز به آموزشی باشه، در حد توان راهنمایی و آموزش نیروهاتون رو هم بر عهده خواهیم گرفت.

خیلی به من لطف خواهید کرد اگر این پست را در همه ی گروه های فنی و بیزنسی تان منتشر کنید.
متاسفانه فعلا فقط از طریق اکانت تلگرام @StartupNerd وشماره 09308282925 در خدمت شما و پاسخگو خواهم بود.

🫂 مجددا از شما خواهش میکنم این پست رو (در همه ی گروه های خودتون که فکر میکنید ممکنه کسی به توانایی ما نیاز داشته باشه) بازنشر کنید
11👍5🔥1
صف (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
جایگزین‌هایی برای کتابخانه‌های محبوب AutoMapper و MediatR

همانطور که احتمالا در جریان هستید، دو کتابخانه محبوب و پرکاربرد یعنی AutoMapper و MediatR قرار است به‌زودی نسخه‌های تجاری داشته باشند و دیگر کاملاً متن‌باز نخواهند بود. جیمی بوگارد، توسعه‌دهنده اصلی این پروژه‌ها، اعلام کرده که برای ادامه توسعه و پشتیبانی، باید مدل تجاری را تهیه کنید.

❗️این یعنی ممکن است در آینده برای استفاده از نسخه‌های جدید یا پشتیبانی، نیاز به پرداخت هزینه باشد.

پس اگه در پروژه‌های خود از این پکیج‌ها استفاده می‌کنید، باید زودتر تصمیم بگیرید که می‌خواهید از چه جایگزین‌هایی استفاده کنید. یا این که خب پولش رو بدید :)

البته خیلی هم بد نشد! Automapper داشت از Reflection استفاده می‌کرد در حالی که جایگزین‌هایی ساخته شده‌اند که زمان کامپایل Mapping را انجام می‌دهند و حداقل ۴ برابر سرعت بهتر و همچنین استفاده منابع کمتری نیاز دارند.

به هر حال جایگزین‌های متنوعی وجود دارد ولی بررسی‌هایی که من برای پروژه‌های فعال انجام دادم به دو نتیجه رسیدم که اینجا مطرح می‌کنم، ممنون می‌شم اگه پیشنهاد بهتری دارید یا چنانچه موافق هستید، توی کامنت همین پست نظر خود را به اشتراک بذارید

این دو گزینه Mapperly و Mapster هستند.

بین اینها هم از لحاظ آپدیت بودن سورس کد گیت هاب، راحتی بهتر برای دیباگ و رفع خطای بهتر و ... هم از Mapperly استفاده می‌کنم.

🔗 در این لینک به مقایسه اجمالی بین Mapper ها پرداخته.

در مورد MediatR چه پیشنهادی دارید و به چه نتیجه‌ای رسیدید؟ لطفا تجربه خود را با ما به اشتراک بگذارید ...

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

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

______
116👍7🔥3👏1
متغیرهای محلی با نوع ضمنی (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
تجربه معماری شش ضلعی در نتفلیکس

وقتی تیم Studio Workflows در نتفلیکس تصمیم گرفت اپلیکیشن جدیدی برای مدیریت تولید محتوا بسازد، با چالشی بزرگ روبه‌رو شد: داده‌هایی که نیاز داشتند، در سیستم‌های مختلف پخش شده بود — از gRPC گرفته تا GraphQL و JSON API.

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

نتیجه؟ وقتی مجبور شدند منبع داده را از JSON API به GraphQL تغییر دهند، بدون آنکه منطق اصلی برنامه دست بخورد!

این معماری کمک کرد تا:

- منطق کسب‌وکار را از منابع داده جدا کنند.

- تست‌نویسی راحت‌تر و سریع‌تری داشته باشند.

- برای تغییرات آینده آماده باشند.

اگه دوست داری بیشتر درباره‌ی این تجربه بخونی، این مقاله‌ی نتفلیکس رو از دست نده:

🔗 تجربه‌ی نتفلیکس با معماری شش‌ضلعی یا Hexagonal Architecture

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

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

______
1👍85🔥2
مدیریت بهتر سرویس های self-hosted

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

از دیپلوی کردن گرفته تا مدیریت بک‌آپ‌ها و نسخه‌های مختلف و Environment های متفاوت که کنترل این موارد به صورت دستی مشکل است و علاوه بر آن ریسک ایجاد مشکل در سرویس‌ها را بالا می‌برد.

ابزارهای متنوعی برای مدیریت این موضوع وجود دارد مثل Heroku، Vercel یا Netlify که محدودیت‌های زیادی دارند.

- ابزاری اوپن سورس و رایگان وجود دارد به نام Coolify

ابزاری اوپن‌سورس و سلف‌هاستد (self-hosted) که به شما اجازه می‌دهد خیلی راحت پروژه‌های خود را روی سرور خود دیپلوی و مدیریت کنید.
بدون نیاز به کلی کانفیگ عجیب غریب، می‌توانید با چند کلیک ساده سرویس‌هایی مثل دیتابیس، اپلیکیشن‌های داکری، یا حتی پروژه‌های Next.js و Laravel و Asp.net و ... را ران کنید.

🔗 آدرس گیت‌هاب.

📖 مستندات کامل.

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

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

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

______
113🔥4👍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
اجرای مستقیم فایل‌های سی‌شارپ با dotnet run

آیا تا به حال برای تست یک کد ساده سی‌شارپ مجبور بوده‌اید پروژه بسازید و فایل .csproj درست کنید!

با نسخه جدید NET 10. می‌تونید فایلی ساده مثل app.cs را مستقیم با دستور زیر اجرا کنید:
dotnet run app.cs


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

برای اضافه کردن پکیج‌های NuGet مستقیم داخل فایل:
#:package Humanizer@2.14.1
using Humanizer;

Console.WriteLine(DateTime.Now.AddDays(-3).Humanize());


برای مشخص کردن نوع SDK پروژه:
#:sdk Microsoft.NET.Sdk.Web

var app = WebApplication.Create();
app.MapGet("/", () => "Hello from ASP.NET Core!");
app.Run();


برای تنظیم ویژگی‌های Build مثل نسخه زبان:
#:property LangVersion preview

Console.WriteLine("Using C# preview features!");



نهایتا می‌توان همین فایل را به پروژه‌ای کامل هم تبدیل کرد:
dotnet project convert app.cs


📖 مستندات کامل را اینجا ببینید.

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

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

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

______
112👍5🔥2
آیا هوش مصنوعی جای برنامه‌نویسان را می‌گیرد؟

شاید بهتر باشد بپرسیم: کدام برنامه‌نویسان با هوش مصنوعی جایگزین می‌شوند؟ در تیم CrystaCode، استفاده از ابزارهایی مثل GitHub Copilot باعث شده توسعه‌دهندگان ارشد بتوانند کاری را که قبلاً یک تیم در ۱۰ روز انجام می‌داد، تنها در ۴ ساعت به پایان برسانند. این یعنی مسیر سنتی رشد از طریق بازبینی کد و انجام کارهای تکراری، حالا فشرده‌تر و سریع‌تر شده. ابزارهای هوش مصنوعی دیگر فقط تکمیل‌کننده نیستند؛ آن‌ها به همکارانی تبدیل شده‌اند که تفکر معماری، درک سیستم و مهارت در طراحی راه‌حل را انجام می‌دهند.

در این چشم‌انداز جدید، توسعه‌دهنده‌ای موفق خواهد بود که بتواند با هوش مصنوعی همکاری کند، نه اینکه با آن رقابت کند. مهارت‌هایی مثل توانایی طراحی end-to-end، درک کسب‌وکار و ارائه خروجی مستقل، حالا ارزشمندتر از صرفاً نوشتن کد هستند. توصیه من به برنامه‌نویسان تازه‌کار این است: سریع‌تر ارشد شوید. آینده منتظر شما نمی‌ماند، بلکه با سرعت در حال حرکت است.

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

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

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

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

______
5👍92🔥2
معرفی کلی 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
بهبود عملکرد JSON در دات‌نت با حذف Reflection!

در اپلیکیشن‌های دات‌نت که در حجم بالا با JSON سروکار دارند، استفاده از JsonSerializer باعث کندی در شروع برنامه، مصرف زیاد حافظه و کاهش سرعت می‌شود. دلیل این موضوع استفاده از Reflection در زمان اجراست که منابع زیادی مصرف می‌کند.

راه‌حل:
در دات‌نت ۶ قابلیت جدیدی معرفی شده: Source Generator برای System.Text.Json. این ابزار در زمان کامپایل کدهای لازم برای سریال‌سازی و دی‌سریال‌سازی را تولید می‌کند، و دیگر نیازی به Reflection در زمان اجرا نیست!

مزایای این موضوع:
- افزایش سرعت سریال‌سازی تا ۱.۶ برابر
- کاهش زمان شروع برنامه
- کاهش مصرف حافظه
- سازگاری بهتر با trimming و کاهش حجم نهایی اپ


public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
}


حالا با استفاده از Source Generator:
[JsonSerializable(typeof(Person))]
internal partial class MyJsonContext : JsonSerializerContext { }


و برای سریال‌سازی:
var person = new Person { FirstName = "Jane", LastName = "Doe" };
var json = JsonSerializer.Serialize(person, MyJsonContext.Default.Person);



📎 برای جزئیات بیشتر، مطلب کامل را اینجا بخوانید.

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

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

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

______
111👍4🔥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
🚀 کارگاه GenAI/LLM Fundamentals for Business People
👤 توسط : مهران داودی

📅 تاریخ: چهارشنبه، ۲۶ شهریور ۱۴۰۴
🕒 زمان:
- ساعت ۱۱:۳۰ صبح (تورنتو)
- ساعت ۵:۳۰ عصر (اروپا)
- ساعت ۷:۰۰ شب (ایران)

🚀 «مبانی GenAI و مدل‌های زبانی بزرگ (LLM) برای افراد بیزنسی»
این کارگاه برای مدیران و متخصصان کسب‌وکار طراحی شده که می‌خواهند درک دقیقی از کاربردهای عملی هوش مصنوعی مولد و مدل‌های زبانی بزرگ در فضای واقعی کسب‌وکار داشته باشند. چه در آغاز مسیر یادگیری هوش مصنوعی باشید و چه به دنبال تعمیق دانش خود، این ورکشاپ پایه‌های ضروری برای حرکت در مسیر پرشتاب GenAI را در اختیار شما قرار می‌دهد.

شرکت برای همه آزاد و رایگان است.
▫️اینجا ثبت نام کنید:
https://www.linkedin.com/feed/update/urn:li:activity:7372270104853610496/

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

______
7👏3🔥1
Software Philosophy pinned «🚀 کارگاه GenAI/LLM Fundamentals for Business People 👤 توسط : مهران داودی 📅 تاریخ: چهارشنبه، ۲۶ شهریور ۱۴۰۴ 🕒 زمان: - ساعت ۱۱:۳۰ صبح (تورنتو) - ساعت ۵:۳۰ عصر (اروپا) - ساعت ۷:۰۰ شب (ایران) 🚀 «مبانی GenAI و مدل‌های زبانی بزرگ (LLM) برای افراد بیزنسی»…»
ساده‌سازی Property ها با کلمه کلیدی field

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

در نسخه‌های قبلی سی‌شارپ، وقتی یک property تعریف می‌شد و قصد داشتید در get یا set به فیلد پشتیبانش دسترسی داشته باشید، باید آن فیلد دستی تعریف می‌شد. اما حالا با filed ، می‌توان از فیلد پنهانی‌ای که کامپایلر خودش برای property تولید می‌کند استفاده کرد.

🔘 روش قدیمی (قبل از اضافه شدن field):
private string _email;

public string Email
{
get => _email;
set
{
if (!value.Contains("@"))
throw new ArgumentException("Invalid email address");
_email = value;
}
}

در اینجا:
- باید فیلد _email را جداگانه تعریف می‌کردیم.
- در get و set به آن فیلد دستی اشاره می‌کردیم.

🟣 روش جدید با fileld:
public string Email
{
get => field;
set
{
if (!value.Contains("@"))
throw new ArgumentException("Invalid email address");
field = value;
}
}

در این نسخه:
- نیازی به تعریف فیلد جداگانه نیست و کامپایلر خودش یک فیلد پنهان برای Email می‌سازد.

🔗 در اینجا بیشتر بخوانید.

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

#نگار_قاسمی (لینکدین)

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

______
2👍195🔥1
وقتی تعداد ورودی‌ها مشخص نیست، params وارد می‌شود!

در دنیای توسعه نرم‌افزار، همیشه با توابعی مواجه می‌شویم که باید انعطاف‌پذیر باشند؛ یعنی بتوانند با ورودی‌های مختلف و تعداد متغیر از داده‌ها کار کنند. زبان سی‌شارپ با کلمه کلیدی params این امکان را فراهم کرده‌است تا بدون دردسر، توابعی بنویسیم که مثل یک میزبان خوش‌برخورد، هر تعداد مهمان را با آغوش باز بپذیرند!

🔘مثال:
public static void LogErrors(params string[] errorMessages)
{
foreach (var msg in errorMessages)
{
Console.WriteLine($"[ERROR] {DateTime.Now}: {msg}");
}
}

🔘 استفاده از تابع:
LogErrors("خطا در اتصال به دیتابیس");
LogErrors("کاربر یافت نشد", "توکن منقضی شده", "دسترسی غیرمجاز");


نکات مهم:
- فقط یک پارامتر می‌تواند params باشد و باید آخرین پارامتر تابع باشد.
- نوع داده‌ی params باید آرایه‌ای باشد (مثلاً int[], string[]).
- اگر هیچ مقداری ارسال نشود، آرایه خالی می‌شود و تابع بدون خطا اجرا می‌شود.

🎯 مزیت این روش:
- نیازی به ساخت آرایه نیست
- تابع با هر تعداد پیام کار می‌کند
- کد خواناتر و تمیزتر

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

#نگار_قاسمی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy
_______
👍71