| کانال توسعه‌دهندگان سی‌شارپ |
1.03K subscribers
19 photos
3 videos
21 links
⭕️ کانال توسعه‌دهندگان سی‌شارپ دولوپیکس

💠 دولوپیکس | جامعه توسعه‌دهندگان ایرانی

💎 @Developix
🚀 Developix.ir

📌 پشتیبانی و تبلیغات:
@DevelopixSupport
Download Telegram
دات نت 8 به طور رسمی منتشر شد
لینک دانلود:

https://dotnet.microsoft.com/en-us/download/dotnet/8.0

👤 QWxp

💎 Channel: @DevelopixCSharp
👍82🔥1
لایو دوم مربوط به انتشار دات نت که امشب ساعت هشت هست رو میتونید از لینک زیر تماشا کنید
https://www.youtube.com/watch?v=vU-iZcxbDUk


👤 QWxp

💎 Channel: @DevelopixCSharp
👍41
احتمالا شده که موقع کار با Minimal API ها نیاز شده که یه سرویسی رو اینجکت کنید و ازش استفاده کنید.

با اتریبیوت [FromServices] مانند کد بالا می‌تونید اون سرویس رو از DI container بگیرید و داخل کدتون استفاده کنید.

👤 MHReza

💎 Channel: @DevelopixCSharp
3👍3🔥2
توی Minimal API ها بعضی وقت‌ها پارامترهاتون زیاد میشه و خوانایی کدتون رو پایین‌تر میاره، می‌تونید مثل عکس بالا اون‌ها رو توی یک رکورد تعریف کنید و با اتریبیوت [AsParameters] از اون استفاده کنید.

👤 MHReza

💎 Channel: @DevelopixCSharp
👍142🔥2
Forwarded from | Codilo |
🍉 یلدای امسال رو کُدیلویی بگذرونید!

🍓 تا پایان روز جمعه با دعوت دو کاربر جدید به کدیلو، فایل های کدیلو رو رایگان دریافت کنید

🥝 یلدای خوبی داشته باشید (:

💎 @Codilo
👍4
Forwarded from Developix Support
🔴 شتابان هاست 🔴

🔰 تخفیف ویژه 12 درصدی برای
خرید انواع🔹هاست🔹سرور
در شتابان هاست به مناسبت فرا رسیدن عید نوروز 🥳:


https://shetabanhost.com/
🌟 کد تخفیف اختصاصی:
shetabanhost


🔗 https://shetabanhost.com/

🌐 پشتیبانی ۲۴ ساعته شتابان هاست👇👇

☎️ 024-91311031
💎 Channel: @shetabanhostcom
31👍24🔥13
This media is not supported in your browser
VIEW IN TELEGRAM
#VisualStudio #Debug #Tip

🏕 تا الان خیلی شده که بخوام یک حلقه رو دیباگ کنم و برای رسیدن به اون سناریو مورد نظر، لازم باشه دائما continue بزنم تا برسم به اون نقطه. ولی خب با این قابلیت Visual Studio می‌تونید به‌راحتی برای دیباگ کردن condition و action قرار بدید و طبعا کارتون خیلی راحت‌تر می‌شه.

👤 Mahdiyar

💎 Channel: @DevelopixCSharp
Please open Telegram to view this post
VIEW IN TELEGRAM
10👍3🔥2
Forwarded from TakShow | تک شو
This media is not supported in your browser
VIEW IN TELEGRAM
دوره آموزشی DesignPattern in C#
برپایه دو کتاب مرجع انگلیسی
وضعیت دوره: درحال برگزاری
سطح دوره: مقدماتی تا پیشرفته
مشاهده دوره :https://tak-show.ir/ShowCourse/2
ببینید چقدر راحت میتوانید متخصص در حوزه برنامه نویسی شوید😉

با ما تک شو:)
#وب سایت آموزشی تک شو
1👍1
زامارین فرم هم آرشیو شد

👤 MHReza

💎 Channel: @DevelopixCSharp
👍7
اصل Dependency Inversion Principle (DIP) در سی‌شارپ و دات‌نت

‌اصل Dependency Inversion Principle (DIP) یکی از اصول مهم در طراحی نرم‌افزار است که در چارچوب SOLID قرار دارد. این اصل می‌گوید ماژول‌های سطح بالا نباید به ماژول‌های سطح پایین وابسته باشند، بلکه هر دو باید به یک رابط (آبستراکشن) وابسته باشند. این اصل باعث می‌شود کد انعطاف‌پذیرتر باشد و راحت‌تر بشود آن را تست کرد.

مثال بدون استفاده از اینترفیس

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

// Email sender class
public class EmailSender
{
public void SendEmail(string message)
{
// Logic to send email
Console.WriteLine($"Sending Email: {message}");
}
}

// User registration service class
public class UserRegistrationService
{
private readonly EmailSender _emailSender;

public UserRegistrationService()
{
_emailSender = new EmailSender();
}

public void RegisterUser(string username)
{
// Logic to register user
Console.WriteLine($"User {username} registered.");

// Sending welcome message
_emailSender.SendEmail("Welcome to our service!");
}
}

// Using the service
class Program
{
static void Main(string[] args)
{
UserRegistrationService registrationService = new UserRegistrationService();
registrationService.RegisterUser("JohnDoe");
}
}






در اینجا کلاس UserRegistrationService به‌طور مستقیم به کلاس EmailSender وابسته است و هر تغییری در کلاس EmailSender می‌تواند باعث تغییرات زیادی در کد شود که نگهداری و تست آن را سخت می‌کند.

استفاده از اینترفیس و تزریق وابستگی

حالا با استفاده از اینترفیس و تزریق وابستگی، سرویس ثبت‌نام کاربر و ارسال پیام رو درست می‌کنیم:

// Message sender interface
public interface IMessageSender
{
void SendMessage(string message);
}

// Implementation of the interface for email sending
public class EmailSender : IMessageSender
{
public void SendMessage(string message)
{
// Logic to send email
Console.WriteLine($"Sending Email: {message}");
}
}

// User registration service with dependency injection
public class UserRegistrationService
{
private readonly IMessageSender _messageSender;

public UserRegistrationService(IMessageSender messageSender)
{
_messageSender = messageSender;
}

public void RegisterUser(string username)
{
// Logic to register user
Console.WriteLine($"User {username} registered.");

// Sending welcome message
_messageSender.SendMessage("Welcome to our service!");
}
}

// Using the service
class Program
{
static void Main(string[] args)
{
IMessageSender messageSender = new EmailSender();
UserRegistrationService registrationService = new UserRegistrationService(messageSender);
registrationService.RegisterUser("JohnDoe");
}
}






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

#تزریق_وابستگی

🔖 #CSharp, #سی_شارپ

👤 Morteza Nazari

💎 Channel: @DevelopixCSharp
Please open Telegram to view this post
VIEW IN TELEGRAM
👍73
تابع بازگشتی چیست؟
تابع بازگشتی یک تابع تو در تو هست که برای رسیدن به نتیجه مورد نظر همواره خودش رو صدا می‌زنه. برای مثال برای به دست آوردن فاکتوریل یک عدد می‌تونیم از تابع بازگشتی زیر استفاده کنیم:
int factorial(int x) {
if (x == 1)
return 1;
else
return x * factorial(x-1);
}



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

🔖 #CSharp, #سی_شارپ

👤 Morteza Nazari

💎 Channel: @DevelopixCSharp
👍13
🌟 آشنایی با مفهوم lock در سی‌شارپ 🔒

در برنامه‌نویسی، به خصوص در محیط‌های چندنخی (multithreading)، مدیریت همزمانی (Concurrency) یکی از چالش‌های مهم است. برای جلوگیری از بروز مشکلات ناشی از دسترسی همزمان به منابع مشترک، از کلمه کلیدی lock در سی‌شارپ استفاده می‌شود.

📌 کاربرد lock:
- پیشگیری از شرایط رقابتی: زمانی که چند نخ (Thread) سعی می‌کنند به طور همزمان به یک منبع (مانند یک متغیر یا شیء) دسترسی پیدا کنند، ممکن است داده‌ها به درستی پردازش نشوند. lock به ما کمک می‌کند تا فقط یک نخ در یک زمان به یک بخش از کد دسترسی داشته باشد.
- حفظ یکپارچگی داده‌ها: با استفاده از `lock`، می‌توانیم اطمینان حاصل کنیم که تغییرات داده‌ها توسط یک نخ در حال پردازش، با نخ‌های دیگر تداخل نداشته باشد.

✍️ چگونه از lock استفاده کنیم؟

نمونه ساده‌ای از استفاده از lock در سی‌شارپ:

using System;
using System.Threading;

class Program
{
private static int counter = 0;
private static readonly object lockObject = new object();

static void Main()
{
Thread t1 = new Thread(IncrementCounter);
Thread t2 = new Thread(IncrementCounter);

t1.Start();
t2.Start();

t1.Join();
t2.Join();

Console.WriteLine("Final Counter Value: " + counter);
}

static void IncrementCounter()
{
for (int i = 0; i < 1000; i++)
{
lock (lockObject)
{
counter++;
}
}
}
}


📌 این کد چه کاری انجام می‌دهد؟
- دو نخ (t1 و t2) به طور همزمان سعی دارند مقدار متغیر counter را ۱۰۰۰ بار افزایش دهند.
- با استفاده از lock ، فقط یک نخ در هر زمان می‌تواند به کد داخل بلاک lock دسترسی داشته باشد، که به این ترتیب از شرایط رقابتی جلوگیری می‌کند.

📝 نکات مهم:
- از lock برای حفاظت از منابع مشترک استفاده کنید تا از بروز خطاها و مشکلات همزمانی جلوگیری کنید.
- به یاد داشته باشید که استفاده بی‌رویه از lock می‌تواند منجر به کاهش عملکرد برنامه شود؛ بنابراین فقط در مواقع ضروری از آن استفاده کنید.

مزایای lock:
- ساده و آسان: استفاده از lock بسیار ساده است و به راحتی می‌توان آن را در کد پیاده‌سازی کرد.
- محافظت از منابع مشترک: lock به شما کمک می‌کند تا از دسترسی همزمان به منابع جلوگیری کنید و از یکپارچگی داده‌ها اطمینان حاصل کنید.

🔖 #CSharp, #سی_شارپ

👤 ali reza

💎 Channel: @DevelopixCSharp
👍14
در پروژه‌های ASP.NET Core وقتی یک سرویس تعداد زیادی وابستگی دارد، خوانایی، تست‌پذیری و نگهداری کد سخت می‌شود.

ایده‌ی عملی امروز: به‌جای تزریق مستقیم چندین سرویس در یک کلاس، یک Facade یا Aggregate Service بسازید تا زنجیره‌ی وابستگی ساده، قابل تست و خواناتر شود. این رویکرد از Service Locator و constructor bloat جلوگیری می‌کند و مسئولیت‌ها را بهتر جدا می‌کند. 🧩

مثال واقعی: کلاس OrderService که به Inventory، Payment و Notification وابسته است. اول نسخهٔ «بد» با constructor پر از وابستگی‌ها:

<!-- escaped C# code for Telegram -->
public class OrderService
{
private readonly IInventoryService _inventory;
private readonly IPaymentService _payment;
private readonly INotificationService _notification;

public OrderService(IInventoryService inventory, IPaymentService payment, INotificationService notification)
{
_inventory = inventory;
_payment = payment;
_notification = notification;
}

public async Task<bool> PlaceOrderAsync(Order order)
{
if (!await _inventory.ReserveAsync(order)) return false;
var paid = await _payment.ChargeAsync(order);
if (!paid) { await _inventory.ReleaseAsync(order); return false; }
await _notification.SendAsync(order);
return true;
}
}


با الگوی Facade، مجموعهٔ عملیات مرتبط را در یک رابط قرار می‌دهیم تا OrderService ساده شود:

<!-- escaped C# code -->
public interface IOrderProcessor { Task<bool> ProcessAsync(Order order); }

public class OrderProcessor : IOrderProcessor
{
private readonly IInventoryService _inventory;
private readonly IPaymentService _payment;
private readonly INotificationService _notification;

public OrderProcessor(IInventoryService inventory, IPaymentService payment, INotificationService notification) { ... }

public async Task<bool> ProcessAsync(Order order)
{
// همان منطق ترکیبی اینجا قرار می‌گیرد
}
}

public class OrderService
{
private readonly IOrderProcessor _processor;
public OrderService(IOrderProcessor processor) { _processor = processor; }
public Task<bool> PlaceOrderAsync(Order order) => _processor.ProcessAsync(order);
}


نکات عملی:
• با Facade، تست واحد ساده‌تر می‌شود (فقط IOrderProcessor موک می‌شود). 🧪
• مسئولیت‌ها تمیز جدا می‌شوند و هر سرویس کوچک‌تر و تک‌وظیفه‌ای می‌ماند. ✂️
• از تزریق مستقیم تعداد زیادی سرویس در کنترلرها یا سرویس‌های سطح بالا خودداری کنید.

مراجع معتبر: مستندات Microsoft Dependency Injection و الگوهای طراحی در Refactoring.Guru برای جزئیات بیشتر. 📚

شروع به کوچک‌سازی زنجیره‌های تزریق در پروژه کنونی کنید و تغییرات را با تست‌های واحد همراه کنید — تاثیرش را سریع احساس خواهید کرد. 🚀

🔖 #CSharp #سی_شارپ #Facade #DependencyInjection #SOLID #C# #ASP_NET_Core

👤 Developix

💎 Channel: @DevelopixCSharp
2👍1
🔹 یک تکه کد زیر مربوط به CSharp است که روی رفتار closure و async/await در حلقه تاکید دارد.

خروجی نهایی اجرای متد Main چیست؟

(ترتیب و مقدار دقیق خطوطی که در Console چاپ می‌شوند را بنویسید.)

🔖 #CSharp #سی_شارپ

👤 Developix

💎 Channel: @DevelopixCSharp
1
‏Dependency Injection تمیز در ASP.NET Core برای تست‌پذیری بهتر ⚙️

یکی از مهم‌ترین قدم‌ها برای Clean Code در پروژه‌های ASP.NET Core این است که وابستگی‌ها را مستقیم new نکنیم، بلکه از Dependency Injection استفاده کنیم. این کار هم کد را تمیزتر می‌کند، هم تست‌پذیری و امکان تغییر پیاده‌سازی‌ها را بالا می‌برد. 💡

فرض کنید در یک Web API کنترلری دارید که مستقیم وابسته به Service است:

public class OrdersController : ControllerBase
{
private readonly OrderService _orderService;

public OrdersController()
{
_orderService = new OrderService();
}

[HttpGet("api/orders/{id}")]
public async Task<IActionResult> Get(int id)
{
var order = await _orderService.GetByIdAsync(id);
return order is null ? NotFound() : Ok(order);
}
}


این طراحی چند مشکل جدی دارد:

• کنترلر مستقیماً به OrderService Couple شده است.
• تست Unit برای کنترلر سخت است، چون نمی‌توان Mock تزریق کرد.
• در آینده اگر سرویس عوض شود (مثلاً کش اضافه شود)، باید خود کنترلر را تغییر بدهید.

راه تمیزتر این است که یک Interface تعریف کنید و آن را از DI Container تزریق کنید:

public interface IOrderService
{
Task<Order?> GetByIdAsync(int id);
}

public class OrderService : IOrderService
{
private readonly AppDbContext _db;

public OrderService(AppDbContext db)
{
_db = db;
}

public Task<Order?> GetByIdAsync(int id)
=> _db.Orders.FindAsync(id).AsTask();
}


حالا کنترلر فقط Interface را می‌شناسد:

[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
private readonly IOrderService _orderService;

public OrdersController(IOrderService orderService)
{
_orderService = orderService;
}

[HttpGet("{id}")]
public async Task<IActionResult> Get(int id)
{
var order = await _orderService.GetByIdAsync(id);
return order is null ? NotFound() : Ok(order);
}
}


و در Program.cs (یا Startup قدیمی‌ها):

builder.Services.AddScoped<IOrderService, OrderService>();


مزیت‌ها 🧩

• تست‌پذیری بالا: در تست‌ها می‌توان یک FakeOrderService یا Mock تزریق کرد.
• پیاده‌سازی قابل‌تعویض: بدون تغییر کنترلر می‌توانید CachingOrderService اضافه کنید.
• رعایت اصل D از SOLID (Dependency Inversion): وابستگی به Abstraction نه Concrete Class.

برای مطالعه بیشتر، مستندات رسمی مایکروسافت درباره DI در ASP.NET Core خیلی شفاف و به‌روز است:
Microsoft Learn - Dependency injection in ASP.NET Core

قدم‌به‌قدم اگر وابستگی‌های مستقیم را به شکل Interface + DI تبدیل کنید، معماری اپلیکیشن تمیزتر، منعطف‌تر و آماده‌ٔ رشد می‌شود. 🚀

🔖 #CSharp #سی_شارپ #C# #_NET #ASP_NET_Core #Dependency_Injection #SOLID #Clean_Code

👤 Developix

💎 Channel: @DevelopixCSharp
👍31
در نمونه‌کد بالا متد GetUsersByRoleAsync در نسخهٔ اول به‌خاطر فچ‌کردن همه رکوردها در حافظه و بعد فیلتر کردن با Where روی List<T>، هم Memory مصرفی را بالا می‌برد و هم روی دیتابیس‌های بزرگ باعث افت شدید Performance می‌شود. در مقابل، در نسخهٔ دوم با نگه داشتن Query به صورت IQueryable<User> و استفاده از Where قبل از ToListAsync، فیلتر روی خود دیتابیس انجام می‌شود و فقط دادهٔ موردنیاز لود می‌شود. در سناریوهایی که جدول‌های بزرگ دارید یا روی Cloud Database کار می‌کنید، این الگو باعث کاهش چشمگیر حجم دادهٔ منتقل‌شده و بهبود زمان پاسخ متدهای Repository خواهد شد. همچنین با برگرداندن IReadOnlyList<User> به جای List<User>، به Contract بهتری از نظر Encapsulation و جلوگیری از Mutation ناخواسته می‌رسید.

🔖 #CSharp #سی_شارپ

👤 Developix

💎 Channel: @DevelopixCSharp
👍7
استفاده حرفه‌ای از ConfigureAwait(false) در async/await

خیلی وقت‌ها توی کتابخونه‌ها و لایه‌های غیر UI، از async/await استفاده می‌شه ولی ناخواسته Performance و Scale خراب می‌شه؛ فقط به خاطر برنگشتنِ درست به Thread قدیمی.

نکتهٔ مهم اینه: در کدهای غیر UI (مثل لایهٔ Data Access، Service، Library) معمولاً نیازی نیست بعد از await برگردیم به همون SynchronizationContext قبلی. اینجاست که 🧠 ConfigureAwait(false) کمک می‌کنه.

ایده:
هرجا در Library Code هستیم و بعد از await به Context قبلی نیاز نداریم، از ConfigureAwait(false) استفاده کنیم تا:
- Deadlockهای کلاسیک در ASP.NET قدیمی کمتر بشه
- Performance بهتر بشه چون نیاز به Capture/Restore Context نیست

مثال ساده در یک Service غیر UI:
public async Task<UserDto> GetUserAsync(int id)
{
// فرض: این متد توی لایه Service یا Repository صدا زده می‌شه
using var client = new HttpClient();

var response = await client
.GetAsync($"https://api.example.com/users/{id}")
.ConfigureAwait(false);

response.EnsureSuccessStatusCode();

var json = await response.Content
.ReadAsStringAsync()
.ConfigureAwait(false);

return JsonSerializer.Deserialize<UserDto>(json)!;
}


📌 نکات مهم:
- توی UI (WPF, WinForms, MAUI) یا Razor Pages که بعد از await می‌خوای کنترل‌های UI رو آپدیت کنی، از ConfigureAwait(false) استفاده نکن چون به Thread UI برنمی‌گردی.
- در ASP.NET Core به‌خاطر نداشتن SynchronizationContext کلاسیک، مشکل Deadlock خیلی کمتره؛ ولی هنوز هم برای Libraryهای عمومی، استفاده از ConfigureAwait(false) یک Practice خوب حساب می‌شه.
- سعی کن این الگو رو توی کل لایه‌های Library یک‌دست نگه داری تا رفتار کد قابل‌پیش‌بینی بمونه.

برای توضیح رسمی مایکروسافت دربارهٔ async/await و Context:
مستندات async در C# (Microsoft Docs)

امتحان این روش توی Serviceها و Libraryها، مخصوصاً زیر لود بالا، خیلی زود توی لاگ‌ها و Performance خودش رو نشون می‌ده 🚀

🔖 #CSharp #سی_شارپ #CSharp #async #ConfigureAwait #Performance #_NET

👤 Developix

💎 Channel: @DevelopixCSharp
🔥3
این کد C# را در نظر بگیرید:

public class UserService
{
private static HttpClient _client = new HttpClient();

public async Task<string> GetUserNameAsync(int id)
{
_client.BaseAddress = new Uri("https://api.example.com/");
_client.DefaultRequestHeaders.Clear();
_client.DefaultRequestHeaders.Add("X-Request-Id", Guid.NewGuid().ToString());

var response = await _client.GetAsync($"users/{id}");
response.EnsureSuccessStatusCode();

return await response.Content.ReadAsStringAsync();
}
}


در این پیاده‌سازی از static HttpClient استفاده شده، اما همچنان یک Memory Leak / Thread-Safety Anti Pattern جدی در نحوه تنظیم BaseAddress و DefaultRequestHeaders وجود دارد که در سناریوهای چند-ترد یا چند-ریکوئست می‌تواند مشکل‌ساز شود.

چه چیزی باید در این کلاس اصلاح شود تا استفاده از HttpClient هم ایمن‌تر و هم بدون این Anti Pattern باشد؟

🔖 #CSharp #سی_شارپ

👤 Developix

💎 Channel: @DevelopixCSharp
👍31
خیلی از Memory Leakهای ریز تو پروژه‌های #CSharp از یه چیز ساده شروع می‌شن: فراموش‌کردن Dispose روی resourceهایی مثل HttpClient، SqlConnection، فایل‌ها و… 😅

تو دات‌نت جدید، using راحت‌تر و خواناتر شده و اگر درست استفاده بشه، هم کد تمیزتر می‌شه هم از نشت حافظه و handleها جلوگیری می‌کنه. 👇

۱️⃣ الگوی قدیمی using بلاکی
using (var stream = File.OpenRead("data.json"))
using (var reader = new StreamReader(stream))
{
var content = reader.ReadToEnd();
Console.WriteLine(content);
}

اینجا به‌محض خروج از بلاک، هر دو object به‌صورت خودکار Dispose می‌شن.

۲️⃣ الگوی جدید using declaration (از C# 8 به بعد)
برای کاهش nesting و خوانایی بیشتر:
using var stream = File.OpenRead("data.json");
using var reader = new StreamReader(stream);

var content = reader.ReadToEnd();
Console.WriteLine(content);
// در انتهای متد، خودشون Dispose می‌شن

تو این حالت، scopeِ using var کل متده؛ یعنی پایان متد = زمان Dispose. این الگو توی متدهای کوتاه و تمیز عالی جواب می‌ده و از بلاک‌های تو در تو کم می‌کنه. 💡

۳️⃣ نکته مهم در متدهای طولانی
اگر متد خیلی طولانیه و resource فقط تو یه بخش کوچیک لازم می‌شه، بهتره همون الگوی بلاکی رو نگه داری تا resource زودتر آزاد بشه و تا آخر متد تو حافظه نمونه.

۴️⃣ async و IAsyncDisposable
برای کلاس‌هایی که IAsyncDisposable رو پیاده‌سازی می‌کنن (مثلاً بعضی clientهای شبکه):
await using var client = new SomeAsyncClient();
await client.DoWorkAsync();

اینجا در انتهای scope، به‌جای Dispose، متد DisposeAsync صدا زده می‌شه و resourceها به‌شکل async آزاد می‌شن.

جمع‌بندی: استفاده درست از using (به‌خصوص using var و await using) یه راه خیلی ساده و کاربردی برای جلوگیری از Memory Leak و تمیز نگه‌داشتن کده. چند جای پروژه رو که resource سنگین دارن چک و این الگو رو اعمال کن؛ تأثیرش تو performance و پایداری سرویس کاملاً قابل لمسه. 🚀

🔗 مرجع رسمی Microsoft Docs:
https://learn.microsoft.com/dotnet/csharp/language-reference/statements/using

🔖 #CSharp #سی_شارپ #C# #using #dispose #memory #performance #_NET

👤 Developix

💎 Channel: @DevelopixCSharp
1