3509
چکیدهای از مفاهیم به روز مهندسی نرم افزار برای مهندسین نرمافزار. معماری نوین نرمافزار، تکنولوژیهای برنامه نویسی جدید
هوش مصنوعی، آمادهی آزمون؟ با skUnit بررسیاش کن!
تصور کنید در حال ساختن یک اپلیکیشن هوش مصنوعی هستید که قرار است با کاربرها گفتوگو کند، تصمیم بگیرد، و حتی گاهی شوخی کند! همه چیز عالی است... تا وقتی که باید مطمئن شوید مدل واقعاً همان کاری را میکند که انتظار دارید. اینجاست که skUnit مثل یک قهرمان وارد صحنه میشود!
🎬 داستان از کجا شروع شد؟
در دنیای داتنت، تستنویسی همیشه بخشی جدی و خشک بوده. اما وقتی پای هوش مصنوعی وسط میآیدد، دیگر نمیتوانید فقط بگویید "این تابع درست کار کرد یا نه؟" باید بپرسید:
❓ آیا مدل واقعاً فهمید کاربر چه گفت؟
❓ آیا جوابش منطقی بود؟
❓ آیا توانست با ظرافت تابعی خاص را صدا بزند؟
حساسیت جایی بالاتر میرود که وقتی تغییری ایجاد میکنید و عمرا به سادگی بفهمدی تمام تغییرات قبلی درست کار میکند یا نه!
و اینجاست که skUnit با رویکردی خلاقانه، تستها را به شکل سناریوهای مکالمهای در قالب Markdown تعریف میکند. ساده، خوانا و درست مانند گفتوگویی واقعی.
🔍 ویژگیهایی که skUnit را خاص میکنند
- تست معنایی پاسخها: بررسی میکند که مدل واقعاً مفهوم را فهمیده است، نه فقط کلمات را.
- تست فراخوانی توابع: مطمئن میشود که مدل دقیقاً همان تابعی را صدا زده که باید.
- مکالمات چندمرحلهای: میتوانید سناریویی کامل از گفتوگوی کاربر با مدل را تست کنید.
- خروجیهای قابل فهم: نتایج تستها به شکل واضح و قابل تحلیل نمایش داده میشوند.
- پشتیبانی از چندین اجرا: چون مدلهای زبانی گاهی نوسان دارند، میتوانید چند بار تست را اجرا کنید و نرخ موفقیت تعیین کنید.
🔗 پیشنهاد میکنم سری به گیتهاب skUnit بزنین.
___________
⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنتها به اشتراک بگذارید.
#نگار_قاسمی (لینکدین)
کانال تلگرام:
@SoftwarePhilosophy
________
مهاجرت از تایپاسکریپت (۲.۵ میلیون خط کد) به سیشارپ
در بلاگ زیر، CTO شرکت Motion توضیح میدهد که چرا تصمیم گرفتهاند کدهای خود را از #typescript به #csharp ببرند...
دلایلی که آورده بسیار قابل توجه هستند و ارزش خواندن و فکر کردن را دارند. ما هم تقریبا به دلایل مشابهی در چند سال گذشته پروژههای جاواسکریپتی خود را به سیشارپ منتقل کردیم.
حتی در دو پروژه اخیر که با شرکتهای کانادایی بوده، اولین کار مهاجرت از کدهای #react به #blazor بوده است.
نظر شما چیه؟
🔗 در این صفحه میتوانید مطلب کامل را بخوانید.
#مهران_داودی (لینکدین - بلاگ)
⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنتها به اشتراک بگذارید.
کانال تلگرام:
@SoftwarePhilosophy
______
بازنویسی تاریخی در دنیای داتنت با 9 NET.!
تیم NuGet در مایکروسافت موفق شد الگوریتم Restore را در نسخه 9 NET. بهطور کامل بازنویسی کند؛ نتیجه؟ افزایش سرعت تا ۱۶ برابر!
📉 زمان Restore برای پروژههای بزرگ از ۳۲ دقیقه به فقط ۲ دقیقه رسید!
چرا این اتفاق افتاد؟
- الگوریتم قبلی بیش از ۱۰ سال بدون تغییر باقی مانده بود.
- پروژههای بزرگ مثل TeamX با کندی شدید مواجه شده بودند.
- ساختار بازگشتی و حافظهبر باعث دیباگ سخت و مصرف منابع بالا شده بود.
چه تغییراتی اعمال شد؟
- حذف ساخت گراف کامل و جایگزینی با ساختار تخت و تصمیمگیری لحظهای.
- بهینهسازی حافظه، کاهش تعداد تکرارها و حذف نودهای تکراری.
- اضافه شدن ویژگیهایی مثل transitive pinning و مدیریت بهتر خطاها.
📈 نتیجه نهایی:
- افزایش چشمگیر بهرهوری توسعهدهندگان.
- صرفهجویی در منابع زیرساختی.
- آمادهسازی برای مقیاسپذیری در پروژههای عظیم.
🔗 توضیحات کامل را در این لینک ببینید.
⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنتها به اشتراک بگذارید.
#حامد_حاجیلو (لینکدین)
کانال تلگرام:
@SoftwarePhilosophy
______
هوشمصنوعی به جز دمو!
تکنولوژیهای هوشمصنوعی معمولا در دموها خیلی جذابن، ولی در استفاده واقعی، «واقعیِ واقعی»، لزوما به اون بامزگی نیستن!
تو این گفتگو قراره در مورد استفاده از هوشمصنوعی تو محصولات واقعی صحبت کنم. اینکه ما با چطور از LLM هایی که ذاتا با Hallucination همراه هستن تو محصولات تجاری استفاده میکنیم.
کمی هم در مورد معماری نرمافزاری و مدل تستنویسی semantic که توی @CrystaCode ازشون استفاده میکنیم میگم و توضیح میدم که چطور باعث میشه با این روشها محصولات قابل اعتمادتر نوشت.
🔗 در این لینک با ما باشید.
تفاوت Add و AddAsync در EF Core به همراهی Hi/Lo!
اگه با Entity Framework Core کار میکنید، شاید برایتان سوال پیش آمده باشد که بهتر است از Add استفاده کنیم یا AddAsync؟
✅ متد Add فقط موجودیت را به Change Tracker اضافه میکند و هیچ ارتباطی با دیتابیس برقرار نمیکند تا زمانی که SaveChanges یا SaveChangesAsync صدا زده شود.
✅ متد AddAsync هم همین کار را میکند، با این تفاوت که در موارد خاص مثل استفاده از Value Generatorهایی مثل HiLo، ممکن است نیاز باشد در لحظهی اضافهکردن، دیتابیس را صدا بزند. برای همین AddAsync به صورت غیرهمزمان طراحی شده است.
در نتیجه اگر از Value Generator خاصی استفاده نمیکنید، Add سریعتر و سبکتر است چون سربار ساخت Task و State Machine را ندارد. اما اگه احتمال میدهید EF نیاز داشته باشد در لحظهی اضافهکردن با دیتابیس ارتباط بگیرد، AddAsync انتخاب بهتری است.
📌 نکته مهم: تفاوت اصلی در زمان اجرای SaveChanges اتفاق میافتد، نه هنگام Add یا AddAsync.
نتیجهگیری: در ۹۹٪ موارد، استفاده از Add کفایت میکند. AddAsync فقط برای سناریوهای خاص مثل HiLo یا Sequence Generatorها کاربرد دارد.
حال Hi/Lo چیست؟
با Hi/Lo میتوانیم شناسهها را سمت کلاینت تولید کنیم، بدون اینکه منتظر ذخیره شدن در دیتابیس بمانیم. EF یک مقدار بالا (Hi) از دیتابیس میگیرد و با یک آفست پایین (Lo) در حافظه، شناسهها را تولید میکند.
🔗 نحوه استفاده از این فیچر را هم میتوانید iamprovidence/hi-lo-with-entity-framework-05910f662164">اینجا به همراه توضیحات کامل بخوانید.
⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنتها به اشتراک بگذارید.
#حامد_حاجیلو (لینکدین)
کانال تلگرام:
@SoftwarePhilosophy
______
داینامیک (dynamic)
#csharp_for_beginners
نوع dynamic یک نوع static است اما وقتی متغیری از نوع dynamic باشد کنترل نوع کامپایلر نادیده گرفته میشود. یعنی معمولاً مانند نوع object رفتار میکند اما کامپایلر فرض میکند که هر عملی روی آن امکانپذیر است بدون اینکه نوع دقیق آن را بداند.
نتیجه این کار این است که وقتی با dynamic کار میکنید لازم نیست بدانید مقدار آن دقیقاً از کجا آمده مثلا از COM API یا یک زبان دینامیک یا از DOM HTML یا بازتاب (reflection).
اگر کد شما نادرست باشد خطا در زمان اجرا ظاهر میشود نه زمان کامپایل
مثال:
class ExampleClass
{
public void exampleMethod1(int i) { }
public void exampleMethod2(string str) { }
}
static void Main(string[] args)
{
ExampleClass ec = new ExampleClass()
dynamic dynamic_ec = new ExampleClass()
dynamic_ec.exampleMethod1(10, 4)
dynamic_ec.someMethod("some argument", 7, null)
dynamic_ec.nonexistentMethod()
}
dynamic d = 1
var testSum = d + 3
var testInstance = new ExampleClass(d)
باکسینگ (Boxing) و آنباکسینگ (Unboxing)
#csharp_for_beginners
باکسینگ (Boxing)
باکسینگ Boxing زمانی اتفاق میافتد که یک مقدار از نوعهای مقداری مثل int یا double به یک نوع مرجع مانند object تبدیل شود. در این فرایند یک شیء جدید در حافظهٔ heap ایجاد میشود و مقدار داخل آن قرار میگیرد. بعد از انجام باکسینگ Boxing، مقدار اولیه و مقدار قرار دادهشده داخل شیء دو دادهی جداگانه خواهند بود و این عملیات به دلیل ایجاد شیء جدید از نظر عملکردی هزینهبر است.
نمونه کد:
int i = 123;
object o = i; // جعبهسازی
i = 456;
Console.WriteLine(i);
Console.WriteLine(o);
int i = 123;
object o = i; // جعبهسازی
try
{
int j = (int)o; // ازجعبهسازی درست
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
int i = 123;
object o = i;
try
{
short x = (short)o; // خطای InvalidCastException
}
catch (InvalidCastException e)
{
Console.WriteLine("Incorrect unboxing");
}
شیء (Object) در سیشارپ
#csharp_for_beginners
در زبان سیشارپ، یک شیء نمایندهی یک نمونه (instance) از یک نوع است، که این نوع میتواند یک کلاس (class) یا یک ساختار (struct) باشد. یک کلاس یا ساختار مانند نقشهای (blueprint) است که مشخص میکند نوع، چه دادهها و رفتارهایی دارد، و شیء بخشی از حافظه است که مطابق این نقشه ایجاد و پیکربندی میشود. برنامه ممکن است چندین شیء از یک کلاس ایجاد کند.
شیءها همچنین میتوانند در متغیرها، آرایهها یا مجموعهها ذخیره شوند. کد مشتری (client code) از این متغیرها برای فراخوانی متدها و دسترسی به خصوصیات عمومی شیء استفاده میکند.
نمونههای ساختار (Struct) و کلاس (Class)
کلاسها
- کلاسها نوع ارجاعی (reference type) هستند.
- متغیر یک شیء کلاس آدرس حافظه آن شیء در heap مدیریتشده را نگه میدارد.
- اگر یک متغیر کلاس به متغیر دیگر نسبت داده شود، هر دو متغیر به همان شیء اشاره میکنند.
- نمونههای کلاس معمولاً با عملگر new ایجاد میشوند.
مثال:
Person person1 = new Person("Leopold", 6);
Person person2 = person1;
person2.Name = "Molly";
// حالا person1.Name هم "Molly" است، زیرا هر دو به یک شیء اشاره دارندPerson p1 = new Person("Alex", 9);
Person p2 = p1;
p2.Name = "Spencer";
// p1 تغییر نکرده است، زیرا p2 کپی مستقل است
اجرای ویندوز داخل داکر!
اگر با داکر (Docker) کار میکنید، پروژه Dockur/Windows یک ابزار فوقالعاده برایتان خواهد بود. این پروژه متنباز به شما اجازه میدهد نسخههای مختلف ویندوز را داخل یک کانتینر داکر اجرا کنید، بدون اینکه نیاز به ماشین مجازی یا نصبهای پیچیده داشته باشید.
ویژگیهای برجسته:
- نصب خودکار ویندوز با انتخاب نسخه دلخواه (از XP تا Windows 11 و حتی Windows Server 2025)
- پشتیبانی از زبانهای مختلف از جمله فارسی
- امکان اتصال از طریق مرورگر یا Remote Desktop
- قابلیت تنظیم مقدار RAM، CPU، اندازه دیسک و حتی عبور USB و دیسکهای فیزیکی
- مناسب برای توسعهدهندگان، تستکنندگان نرمافزار و علاقهمندان به مجازیسازی
🌍 این پروژه در GitHub بیش از ۴۵ هزار ستاره گرفته و توسط هزاران نفر استفاده میشود. برای استفاده فقط کافی است Docker و KVM روی سیستم شما فعال باشد.
📦 نحوه استفاده:
با یک فایل Docker Compose ساده یا دستور CLI میتوانید کانتینر را اجرا کرده و از طریق مرورگر به دسکتاپ ویندوز دسترسی پیدا کنید. همه چیز به صورت خودکار نصب میشود!
🔗 لینک پروژه در گیتهاب:
dockur/windows در GitHub1
اگر دنبال راهی سریع، سبک و قابل تنظیم برای اجرای ویندوز هستید، این پروژه را از دست ندهید. مناسب برای تست نرمافزار، آموزش، یا حتی استفاده روزمره در محیطهای توسعه!
⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنتها به اشتراک بگذارید.
#حامد_حاجیلو (لینکدین)
کانال تلگرام:
@SoftwarePhilosophy
______
🎯 سرویس پرداخت یکپارچه Stripe
اگر قصد دارید در پروژههای خارجی یا بینالمللی پرداخت آنلاین را پیادهسازی کنید، یکی از بهترین گزینهها استفاده از سرویس قدرتمند Stripe است. این سرویس در بسیاری از کشورها و پلتفرمهای جهانی کاربرد دارد و مستندات جامعی برای توسعهدهندگان ارائه کرده است.
در این راهنما که از مستندات رسمی Stripe تهیه شده، مراحل راهاندازی محیط توسعه برای زبان سیشارپ توضیح داده شده است. این مراحل شامل موارد زیر است:
🔧 نصب Stripe CLI
ابزاری خط فرمان برای تعامل مستقیم با APIهای Stripe بدون نیاز به نوشتن کدهای اضافی.
🧰 نصب Stripe SDK برای سیشارپ
کتابخانهای برای ارسال درخواستهای API از داخل پروژههای داتنت، بدون نیاز به نوشتن کدهای تکراری.
🚀 استفاده از API
ساخت یک محصول و تعیین قیمت آن با استفاده از SDK، بهصورت مرحلهبهمرحله و قابل اجرا در محیط تست.
⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنتها به اشتراک بگذارید.
#حامد_حاجیلو (لینکدین)
کانال تلگرام:
@SoftwarePhilosophy
______
و اینک NET Conf Watch Party! 🎂🍰🥂
داتنتکانف امسال امروز (سهشنبه ۲۰ آبان) ساعت ۷:۳۰ شروع میشه. ما قراره تو آنلاین با هم رویداد رو تماشا کنیم. از ساعت ۷ لینک تیمز رو میفرستیم که هر کی دوست داشت بیاد.
نیم ساعت اول یکم گپ میزنیم و با هم آشنا میشیم تا رویداد شروع بشه.
هماهنگی و لینک تیمز تو این گروه انجام میشه: @SoftwarePhilosophyGroup
#مهران_داودی (http://ow.ly/GwIl309lFEm)
کانال تلگرام:
@SoftwarePhilosophy
___
پروپوزال WebMCP، باز هم همکاری مایکروسافت و گوگل!
پیشنهاد میکنم حتما این پروپوزال را دنبال کنید، چون تاثیر زیادی در آینده یکپارچگی مرورگرهایی مثل Edge و Chrome با ابزارهای هوشمصنوعی خواهد داشت.
هوش مصنوعی دارد نحوه تعامل ما با وب را متحول میکند. این بار WebMCP، پیشنهادی از تیمهای Microsoft و Google، قرار است این تعامل را شفافتر و قابلکنترلتر کند. با WebMCP، توسعهدهندگان میتوانند مجموعهای از اکشنها (مثل play، pause، add-todo و ...) را بهصورت MCP Tools مستقیم از طریق API مرورگر در اختیار ایجنتهای هوشمصنوعی قرار دهند.
یعنی بهجای اینکه AI با حدس و گمان از روی DOM یا اسکرینشاتها عمل کند، میتواند از خود کد اپلیکیشن استفاده کند و دقیقاً همان کاری را انجام دهد که توسعهدهنده مشخص کرده است. WebMCP نه تنها دقت و امنیت تعاملات را بالا میبرد، بلکه نقش توسعهدهنده را در عصر عاملهای هوشمند زیاد میکند و عملا قسمتی از کار برنامهنویسی وب به غیرساخت صفحات، فراهم کردن WebMCP های مناسب خواهد بود.
🔗 در این صفحه بیشتر بخوانید.
#mcp #llm #ai
#مهران_داودی (لینکدین - بلاگ)
@SoftwarePhilosophy
______
تجربه کار با Map و پکیجهای مختلف در Blazor و Angular
تیم ما در سالهای اخیر زمان زیادی را برای کار کردن با Map توی بیلیزور گذراند و تجربههای خوبی به دست آوردهایم. انواع مختلف نیازمندیهای Map را توانستیم با MapBox GL و Wrapper سیشارپیای که برایش نوشتیم پیاده سازی کنیم.
اخیرا هم در پروژه دیگری که Angular است از Map استفاده کردیم و چون نیاز خیلی سادهای داشتیم از Leaflet استفاده کردیم.
🔗 در این پست لینکدین بیشتر در مورد این تجربه صحبت کردم و توضیح دادم که دلیل استفاده از هر کدام چه بوده است. خوشحال میشوم اگه تجربه کار در این زمینه را دارید با ما به اشتراک بگذارید.
⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنتها به اشتراک بگذارید.
#حامد_حاجیلو (لینکدین)
کانال تلگرام:
@SoftwarePhilosophy
______
ساختارها در سیشارپ
#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})"
}
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})"
}
فراتر از چتباتها، نزدیکتر به انسان
در دنیایی که هوش مصنوعی هر روز مرزهای تازهای را فتح میکند، مدل جدید GPT-4o از شرکت OpenAI نقطهی عطفی در مسیر تعامل طبیعیتر میان انسان و ماشین به شمار میآید. این مدل چندوجهی با توانایی پردازش همزمان متن، تصویر و صوت، تجربهای بیسابقه از گفتوگوهای هوشمند و واکنشهای لحظهای را فراهم کرده است. نسخه جدید Realtime API نیز با بهرهگیری از قدرت GPT-4o، امکان ساخت دستیارهای صوتی با واکنش سریع، صدای طبیعی و درک عمیقتر از زبان انسانی را فراهم میکند.
ویژگیهای برجسته gpt-realtime:
- تبدیل گفتار به گفتار (Speech-to-Speech): برخلاف مدلهای قبلی که گفتار را به متن و بعد دوباره به گفتار تبدیل میکردند، این مدل مستقیماً گفتار تولید میکند. این باعث کاهش تأخیر و طبیعیتر شدن مکالمه میشود.
- درک بهتر دستورها: مدل میتواند دستورهای پیچیده را دقیقتر دنبال کند، مثل گفتن جملات با لحن خاص یا تکرار دقیق اطلاعات مثل شمارهها و حروف.
- توانایی چندزبانه: میتواند وسط جمله زبان را عوض کند و حتی نشانههای غیرکلامی مثل خنده را تشخیص بدهد.
- صداهای جدید: دو صدای جدید به نامهای Cedar و Marin معرفی شدهاند که طبیعیترین کیفیت گفتار را دارند.
قابلیتهای جدید Realtime API:
- پشتیبانی از تصاویر: حالا میتوانید عکس یا اسکرینشات را همراه با صوت یا متن ارسال کنید تا مدل بتواند درباره آن تصویر صحبت کند.
- تماس تلفنی با SIP: امکان تماس صوتی واقعی از طریق پروتکل SIP فراهم شده است.
- اتصال به سرورهای MCP: برای استفاده از ابزارهای خارجی بدون نیاز به تنظیمات پیچیده.
- قیمتگذاری جدید: هزینهها ۲۰٪ کاهش پیدا کرده و کنترل بیشتری روی طول مکالمهها برای کاهش هزینه فراهم شده است.
🔗 برای آشنایی بیشتر این مطلب را مطالعه کنید.
———
⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنتها به اشتراک بگذارید.
#نگار_قاسمی (لینکدین)
کانال تلگرام:
@SoftwarePhilosophy
_______
گزارش از دیتابیس لازم داری؟ فقط حرف بزن!
تصور کنید وارد یک پنل مدیریتی میشوید، فقط یک جمله ساده تایپ میکنید:
«نمایش مشتریانی که بیش از ۵ خرید داشتهاند»
و بدون اینکه حتی یک خط SQL بنویسید، جدول دقیق با تمام اطلاعات جلو روی شما ظاهر میشود.
نه نیاز به دانش دیتابیس دارید، نه وقت گذاشتن برای نوشتن کوئریهای پیچیده.
این آینده نیست. این حال حاضر توسعه نرمافزار با هوش مصنوعیست.
با ظهور مدلهای زبانی قدرتمند مثل GPT-4، تعامل با دادهها وارد مرحلهای جدید شده است. حال میتوانیم با زبان طبیعی، مثل حرف زدن با یک همکار، از دیتابیس اطلاعات بگیریم.
مرحله اول: دریافت ساختار دیتابیس
برای اینکه GPT-4 بتواند کوئری دقیق تولید کند، ابتدا باید ساختار جدولها و ستونها را بشناسد. با استفاده از EF Core، میتوان لیستی از جدولها و فیلدها را استخراج کرد و به مدل ارسال کرد.
public async Task<string> GetAllTableSchemas()
{
// دریافت اطلاعات جدولها از دیتابیس
}
public async Task<string> GenerateSQLQuery(string userPrompt)
{
var prompt = $"Given the following database schema: {schema}, write a SELECT SQL query for: {userPrompt}";
var response = await openAiClient.GetCompletionAsync(prompt);
return response.Text;
}
public async Task<DataTable> ExecuteQuery(string sql)
{
using var connection = new NpgsqlConnection(connectionString);
var command = new NpgsqlCommand(sql, connection);
var reader = await command.ExecuteReaderAsync();
// تبدیل نتیجه به DataTable
}
دلیگیت (delegate)
#csharp_for_beginners
دلیگیتها (delgate) در زبان سیشارپ نوعی دادهاند که مرجع به یک یا چند متد را نگه میدارند. Delegateها شبیه اشارهگر تابع هستند اما بهصورت شیءگرا پیادهسازی شدهاند. این ویژگی باعث میشود فقط متدهایی با امضای مشخص بتوانند به یک delegate متصل شوند.
برای تعریف یک delegate از کلمه کلیدی delegate استفاده میشود. تعریف delegate مشابه امضای یک متد است و مشخص میکند چه نوع متدی میتواند به آن نسبت داده شود:
public delegate void Callback(string message);
static void DelegateMethod(string message)
{
Console.WriteLine(message);
}
Callback handler = DelegateMethod;
handler("Hello World");static void MethodWithCallback(int a, int b, Callback callback)
{
callback("Result: " + (a + b));
}
Callback handler = DelegateMethod;
handler += AnotherMethod;
سلسله مطالب مرتبط با موضوع MCP ها:
ساخت سرورهای MCP با Azure Functions
مطالب قبلی:
ساخت یک MCP Server ساده با سیشارپ
نگاهی کمی فلسفیتر به MCP
لایو تکمیلی در مورد MCP و LLM ها
پروتکل MCP (Model Context Protocol) راهی نو برای ارتباط بین مدلهای هوش مصنوعی و ابزارهای کاربردی فراهم کرده. حالا با استفاده از Azure Functions میتوانید خیلی راحت سرورهای MCP بسازید و آنها را به صورت ریموت اجرا کنید!
ویژگیهای جذاب:
- استفاده از ویژگی [McpToolTrigger] برای تبدیل فانکشنها به ابزارهای قابل استفاده توسط LLMها.
- ذخیره و بازیابی دادهها از Azure Blob Storage با چند خط کد.
- اتصال مستقیم به VS Code و GitHub Copilot برای تعامل هوشمند با کدها.
فقط کافی است پروژه نمونه را کلون کنید، دستور azd up را اجرا کنید و سرور MCP شما روی Azure بالا میآید! بعد میتوانید با Copilot صحبت کنید و بخواهید کدهای انتخابشده شما را ذخیره کند یا دوباره برایتان بیاورد.
📚 آموزش کامل و کد نمونه را میتوانید در وبلاگ رسمی داتنت بخوانید.
⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنتها به اشتراک بگذارید.
#حامد_حاجیلو (لینکدین)
کانال تلگرام:
@SoftwarePhilosophy
______
کلید اصلی در EF Core: عدد یا GUID؟
وقتی با EF Core کار میکنیم، یکی از تصمیمهای مهم اولیه انتخاب نوع کلید اصلی (Primary Key) است. دو گزینه رایج داریم:
🔹 عدد صحیح (int یا long)
🔹 شناسه یکتا گلوبال (GUID)
هر کدام از این دو گزینه مزایا و معایب خود را دارند:
✅ عدد صحیح (int/long):
- عملکرد بهتر در جستجو و ایندکسگذاری
- خوانایی بیشتر برای انسانها
- حجم کمتر (۴ یا ۸ بایت)
❌ اما:
- در سیستمهای توزیعشده ممکن است باعث تداخل شود.
- قابل پیشبینی بودن مقادیر میتواند امنیت را کاهش دهد.
✅ نوع GUID:
- یکتایی گلوبال، مناسب برای سیستمهای توزیعشده.
- ادغام راحت دادهها از منابع مختلف.
- امنیت بیشتر به خاطر غیرقابل پیشبینی بودن.
- میتوانیم سمت کد موقع ایجاد آبجکت جدید دیتابیسی یک Id جدید اضافه کنیم. Guid.NewGuid که پرفورمنسی بهتر است.
❌ اما:
- عملکرد ضعیفتر نسبت به int
- حجم بیشتر (۱۶ بایت)
- سختتر برای خواندن و تایپ دستی
🔍 جمعبندی:
تصمیم شخصی من با توجه به موضوعاتی که گفته شد این است که از GUID استفاده کنم تا دیگر به ازای هر Add نیازی نباشد که یک بار دیگر سمت دیتابیس بروم و خب فواید دیگری هم برای Guid دارم و آن پرفورمنسی که در مورد int صحبت شد برای من آنچنان Game Changer نبوده است و مزایای int نسبت به مزایای Guid برای من کمتر است
انتخاب شما چی است؟
🔗 توضیحات تکمیلی را engrabdullahabdullah/choosing-the-right-primary-key-in-ef-core-int-vs-guid-64463b57c169">اینجا بخوانید.
⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنتها به اشتراک بگذارید.
#حامد_حاجیلو (لینکدین)
کانال تلگرام:
@SoftwarePhilosophy
______
تولید اطلاعات نادرست با اعتماد به نفس بالا!
توهم (Hallucination) در مدلهای زبانی به حالتی گفته میشود که مدل، اطلاعات نادرست یا ساختگی تولید میکند، در حالی که با اطمینان و لحن قانعکننده آن را ارائه میدهد. این پدیده میتواند شامل اشتباهات تاریخی، علمی، یا حتی ساختن منابع و نقلقولهای جعلی باشد.
تصور کنید از یک مدل زبانی میپرسید: «چه کسی اولین بار نظریه نسبیت را مطرح کرد؟» و پاسخ میدهد: «ایزاک نیوتن در سال ۱۸۷۹». این پاسخ نهتنها اشتباه است (چون نظریه نسبیت متعلق به آلبرت اینشتین است)، بلکه با لحنی قاطع ارائه میشود که میتواند مخاطب را گمراه کند.
چرا مدلها دچار توهم میشوند؟
🔘 هدف آموزشی مدلها: پیشبینی واژهی بعدی
- مدلهای زبانی بر اساس احتمال واژهی بعدی آموزش میبینند، نه بر اساس صحت اطلاعات.
- این یعنی مدلها بیشتر «حدس» میزنند تا «اطلاع» داشته باشند.
🔘نبود دادههای منفی یا بازخورد اصلاحی
- در فرآیند آموزش، مدلها معمولاً فقط با دادههای مثبت تغذیه میشوند.
- اشتباهاتشان اصلاح نمیشود مگر در مراحل خاصی مثل fine-tuning یا RLHF.
🔘تشویق به تولید پاسخهای روان و کامل
- مدلها برای تولید پاسخهایی جذاب و کامل پاداش میگیرند، حتی اگر دقیق نباشند.
- ابراز «ندانستن» اغلب امتیاز کمتری دارد.
🔘فشار ارزیابیهای سطحی
- بسیاری از ارزیابیها فقط دقت زبانی یا شباهت به پاسخهای انسانی را میسنجند.
- صداقت، فروتنی شناختی، یا توانایی تشخیص عدم قطعیت نادیده گرفته میشود.
برای ساخت مدلهایی قابل اعتمادتر، باید هم در آموزش و هم در ارزیابی تغییراتی ایجاد شود. برخی راهکارهای کلیدی عبارتاند از:
🟣 تشویق به ابراز عدم قطعیت
- مدلها باید یاد بگیرند که گاهی «نمیدانم» گفتن بهتر از حدس زدن است.
- این رفتار باید در ارزیابیها پاداش داده شود.
🟣 استفاده از دادههای منفی در آموزش
- آموزش مدلها با نمونههایی از پاسخهای اشتباه و اصلاحشده، به آنها کمک میکند تا بهتر تشخیص دهند چه چیزی نادرست است.
🟣 ارزیابی چندلایه
- علاوه بر دقت زبانی، باید معیارهایی مثل «درستی اطلاعات»، «منبعپذیری» و «فروتنی شناختی» نیز سنجیده شوند.
🟣 افزایش شفافیت مدلها
- مدلها باید بتوانند توضیح دهند که چرا یک پاسخ را دادهاند یا از کجا آن را گرفتهاند.
🔗 در اینجا میتوانید بیشتر بخوانید.
___________
⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنتها به اشتراک بگذارید.
#نگار_قاسمی (لینکدین)
کانال تلگرام:
@SoftwarePhilosophy
________
تغییر مهم در NET 9. برای توسعهدهندگان HTTP
در نسخه جدید NET 9.، رفتار پیشفرض HttpClientFactory تغییر کرده است و بهجای استفاده از HttpClientHandler از SocketsHttpHandler بهعنوان هندلر اصلی استفاده میشود (البته در پلتفرمهایی که قابلیت پشتیبانی داشته باشند).
🔧 این تغییر باعث میشود تا کدهایی که قبلاً هندلر را به HttpClientHandler تبدیل میکردند، با خطای InvalidCastException مواجه شوند.
مثلا کد زیر خطایی که گفته شد را خواهد داد:
services.AddHttpClient("test")
.ConfigurePrimaryHttpMessageHandler((h, _) =>
{
((HttpClientHandler)h).UseCookies = false;
});SocketsHttpHandler با ویژگی PooledConnectionLifetime بهطور پیشفرض تنظیم میشود تا اتصالها بهصورت دورهای بازسازی شوند.
ساخت اپلیکیشنهای هوش مصنوعی با Chroma در NET.
اگر دنبال ارتقای پروژههای NET. با قابلیتهای جستجوی هوشمند هستید، حالا میتوانید از Chroma استفاده کنید، یک پایگاه داده متنباز مخصوص اپهای AI!
📌 اما Chroma چیست؟
پایگاه دادهای برای ذخیرهسازی embeddingها، جستجوی vector، فیلتر متادیتا، full-text search و بازیابی multi-modal (چند رسانهای). مناسب برای پیادهسازی قابلیتهایی مثل جستجوی semantic و RAG.
🛠 چگونه از Chroma استفاده کنیم؟
با پکیج ChromaDB.Client در سیشارپ میتوانید به راحتی به دیتابیس وصل شوید، مجموعهای بسازید، دادهها را اضافه کنید و با vector search، اطلاعات مرتبط را پیدا کنید.
۱. نصب
۲. ساخت یک ChromaClient
using ChromaDB.Client;
var configOptions = new ChromaConfigurationOptions(uri: "http://localhost:8000/api/v1/");
using var httpClient = new HttpClient();
var client = new ChromaClient(configOptions, httpClient);
var collection = await client.GetOrCreateCollection("movies");
var collectionClient = new ChromaCollectionClient(collection, configOptions, httpClient);
آشنایی با دو قابلیت جدید در ویژوال استودیو
اگر با Razor در توسعه وب کار میکنید، خبر خوب اینکه دو قابلیت جدید در Visual Studio و VS Code اضافه شده که حسابی کار شما را راحتتر میکند:
🔹 «استخراج کامپوننت» (Extract to Component):
با این قابلیت میتوانید فقط با چند کلیک، بخشهایی از کد HTML را به یک کامپوننت جداگانه تبدیل کنید. دیگر نیازی به کپیپیست و ساخت دستی فایل نیست!
🔹 «توکنایزر جدید سیشارپ» با پشتیبانی از Roslyn:
این بهروزرسانی باعث میشود Razor بهتر بتواند کدهای سیشارپ را پردازش کند؛ از جمله raw string literals، رشتههای verbatim و حتی دستورهای پیشپردازنده.
📌 این قابلیتها فعلاً در نسخههای جدید Visual Studio و NET 9. فعال هستند و قرار است در NET 10. بهصورت پیشفرض فعال باشند.
🔗 بیشتر بخوانید.
⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنتها به اشتراک بگذارید.
#حامد_حاجیلو (لینکدین)
کانال تلگرام:
@SoftwarePhilosophy
______
تاپلها در سیشارپ
#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}.");
(int a, byte b) left = (5, 10);
(long a, int b) right = (5, 10);
Console.WriteLine(left == right); // True
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);
لینک «با هم کنفرانس داتنت رو ببینیم»!!!
https://teams.microsoft.com/l/meetup-join/19%3a46ecfc4157634db68224484eb717f3ed%40thread.tacv2/1762875140672?context=%7b%22Tid%22%3a%2224fbf492-43a9-4a8f-ba7b-6f12fa9b8d87%22%2c%22Oid%22%3a%22aca9b64a-ea78-46f4-a5b4-b3afd7832f63%22%7d
کلاس لیست (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
______
تعریف Enum
#csharp_for_beginners
یک Enum در واقع نوع دادهای سفارشی است که مجموعهای از ثابتهای عددی نامگذاریشده را در خود نگه میدارد. برای مثال:
enum Season
{
Spring,
Summer,
Autumn,
Winter
}
enum ErrorCode : ushort
{
None = 0,
Unknown = 1,
ConnectionLost = 100,
OutlierReading = 200
}
enum OrderStatus
{
Pending,
Processing,
Shipped,
Delivered
}
[Flags]
public enum Days
{
None = 0,
Monday = 1,
Tuesday = 2,
Wednesday = 4,
Thursday = 8,
Friday = 16,
Saturday = 32,
Sunday = 64,
Weekend = Saturday | Sunday
}
🎬 برنامهنویسی ویدیو با React!
اگر دنبال راهی خلاقانه برای ساخت ویدیو با کدنویسی هستید، ریپازیتوری Remotion یک انتخاب بینظیر است. این فریمورک قدرتمند به شما اجازه میدهد با استفاده از React و تکنولوژیهای وب مثل CSS، SVG، Canvas و حتی WebGL، ویدیوهای کاستوم بسازید.
برای شروع فقط کافی است دستور زیر را اجرا کنید:
npx create-video@latest
ساخت شرطهای پویا با OR در LINQ to SQL
در بسیاری از پروژههای نرمافزاری، نیاز داریم تا بر اساس ورودیهای کاربر، فیلترهایی را به صورت پویا روی دادهها اعمال کنیم. یکی از چالشهای رایج، ترکیب چند شرط با عملگر OR در کوئریهای LINQ است، بهویژه زمانی که از LINQ to SQL استفاده میکنیم.
مشکل کجاست؟
در LINQ، وقتی چند .()Where پشت سر هم استفاده میکنیم، شرطها به صورت AND ترکیب میشوند. اما اگر بخواهیم چند شرط را با OR ترکیب کنیم، نمیتوانیم به راحتی از .()Or استفاده کنیم، چون <<Expression<Func<T, bool چنین متدی ندارد.
راهحل: استفاده از Expression.OrElse
برای ساخت شرطهای OR، باید از Expression.OrElse استفاده کنیم و پارامترهای مشترک را با دقت جایگزین کنیم. در ادامه، روشی ارائه میشود که لیستی از شرطها را دریافت کرده و آنها را با OR ترکیب میکند:
public static Expression<Func<T, bool>> OrElse<T>(IEnumerable<Expression<Func<T, bool>>> expressions)
{
var parameter = Expression.Parameter(typeof(T), "x");
Expression? body = null;
foreach (var expr in expressions)
{
var visitor = new ReplaceParameterVisitor(expr.Parameters[0], parameter);
var visitedBody = visitor.Visit(expr.Body);
body = body == null ? visitedBody : Expression.OrElse(body, visitedBody);
}
return body != null
? Expression.Lambda<Func<T, bool>>(body, parameter)
: x => false;
}
class ReplaceParameterVisitor : ExpressionVisitor
{
private readonly ParameterExpression _oldParam;
private readonly ParameterExpression _newParam;
public ReplaceParameterVisitor(ParameterExpression oldParam, ParameterExpression newParam)
{
_oldParam = oldParam;
_newParam = newParam;
}
protected override Expression VisitParameter(ParameterExpression node)
{
return node == _oldParam ? _newParam : base.VisitParameter(node);
}
}
var filters = new List<Expression<Func<Person, bool>>>
{
p => p.Age > 30,
p => p.Name.StartsWith("ن"),
p => p.IsActive
};
var combined = OrElse(filters);
var result = db.People.Where(combined);
WHERE Age > 30 OR Name LIKE 'ن%' OR IsActive = 1
اپراتورها در سیشارپ
#csharp_for_beginners
زبان سیشارپ مجموعهای از اپراتورها دارد که روی انواع دادههای پایه مثل اعداد، مقدارهای بولی و رشتهها عمل میکنند. با استفاده از این اپراتورها میتوان عبارات مختلف ساخت و محاسبات پیچیده انجام داد. ترتیب اجرا یا همان اولویت اپراتورها مشخص میکند که در یک عبارت ترکیبی، کدام قسمت زودتر ارزیابی شود. اگر بخواهیم این ترتیب پیشفرض را تغییر دهیم، میتوانیم از پرانتز استفاده کنیم.
دستههای اصلی اپراتورها
۱. اپراتورهای حسابی: برای انجام محاسبات ریاضی مثل جمع، تفریق، ضرب، تقسیم و باقیمانده استفاده میشوند.
۲. اپراتورهای مقایسهای: برای مقایسه دو مقدار بهکار میروند، مثل بزرگتر، کوچکتر یا برابر بودن.
۳. اپراتورهای منطقی بولی: برای ترکیب و معکوس کردن مقادیر درست و نادرست (true/false) استفاده میشوند.
۴. اپراتورهای بیتبهبیت و شیفت: برای کار روی بیتهای داخلی دادههای عددی کاربرد دارند.
۵. اپراتورهای برابری: برای بررسی مساوی یا نامساوی بودن دو مقدار استفاده میشوند.
۶. اپراتورهای انتساب و ترکیبی: برای مقداردهی متغیرها یا ترکیب یک عملیات با انتساب بهکار میروند، مانند += یا -=.
۷. اپراتور شرطی سهتایی: یک عبارت شرطی است که بین دو مقدار یکی را انتخاب میکند.
۸. اپراتورهای Null: برای بررسی نال بودن و جایگزین کردن مقدار پیشفرض استفاده میشوند.
۹. اپراتورهای دسترسی به عضو، ایندکس، افزایش یا کاهش و تبدیل نوع: برای دسترسی به اعضای یک شیء، کار با آرایهها، افزایش/کاهش مقدار یا تبدیل نوع داده به نوع دیگر استفاده میشوند.
اولویت و جهت اجرای اپراتورها
اپراتورها در سیشارپ اولویتهای مختلفی دارند. اپراتورهایی با اولویت بالاتر زودتر اجرا میشوند. اگر چند اپراتور در یک سطح اولویت باشند، ترتیب اجرا توسط جهت ارجاع مشخص میشود. اکثر اپراتورهای دوتایی از چپ به راست اجرا میشوند، اما برخی مانند انتساب و اپراتور شرطی از راست به چپ اجرا میشوند.
بهعنوان مثال، عبارت a + b - c بهصورت (a + b) - c محاسبه میشود، ولی عبارت x = y = z به شکل x = (y = z) ارزیابی خواهد شد
ترتیب ارزیابی عملوندها
بهطور پیشفرض، عملوندهای یک اپراتور از چپ به راست محاسبه میشوند. با این حال، برخی اپراتورها شرطی هستند و ممکن است همه عملوندها محاسبه نشوند.
• در اپراتور && اگر عملوند سمت چپ برابر false باشد، سمت راست دیگر بررسی نمیشود.
• در اپراتور || اگر عملوند سمت چپ true باشد، سمت راست اجرا نمیشود.
• در اپراتور ?? یا ??=، اگر مقدار سمت چپ نال نباشد، سمت راست محاسبه نمیشود.
• در اپراتور شرطی سهتایی ?: فقط یکی از شاخهها اجرا میشود.
• در عملگرهای شرطی نال مانند ?. یا ?[]، اگر شیء سمت چپ نال باشد، ادامهی عبارت متوقف میشود
🔗 مطلب کامل را در این لینک میتوانید مطالعه کنید.
⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنتها به اشتراک بگذارید.
کانال تلگرام:
@SoftwarePhilosophy
______