#C یک زبان شی گرا ، ایمن و Managed است که توسط .Net framework برای تولید یک زبان میانی کامپایل می شود.

متغیرها یا متدهای public در هر نقطه از برنامه قابل دسترسی است. متغیرها یا متدهای static در سطح برنامه بدون ایجاد نمونه ای از کلاس در دسترس هستند و void یک modifier نوع است که بیان می کند که متد یا متغیر هیچ مقداری بر نمی گرداند.

یک سازنده یک متد هم نام با نام کلاس و بدون مقدار بازگشتی است. هر زمان که شی ای از یک کلاس ایجاد شود ، سازنده آن به طور خودکار فراخوانی می شود و فیلدهای کلاس را مقداردهی اولیه میکند یا منطقی را پیاده سازی میکند. در صورتی که هیچ سازنده ای در کلاس تعریف نشده باشد #C از یک سازنده پیش فرض که پارامتر ورودی ندارد استفاده می کند. در یک کلاس می توان چندین سازنده با overload های مختلف داشت.

public class Person
{
private string last;
private string first;
public Person(string lastName, string firstName)
{
last = lastName;
first = firstName;
}
// Remaining implementation of Person class.
}
این سوال از من پرسیده شده است  + 
method overloading مکانیزمی برای ایجاد چندین متد با یک نام و امضای منحصر به فرد در یک کلاس است. با تغییر تعداد، تغییر ترتیب و تغییر نوع ورودی ها میتوان overload های مختلفی از متدهای هم نام ایجاد کرد.

بله، میتوان چندین بلوک catch متوالی ایجاد کرد که هر کدام در جواب به exception خاصی اجرا شوند. مثلا میتوان دو بلوک catch داشت که اولی در زمان ایجاد خطای تقسیم بر صفر اجرا گردد (DevideByZeroException) و دیگری در زمانی که سعی داریم در یک آرایه یا لیست به یک ایندکس خارج از محدوده دسترسی پیدا کنیم (IndexOutOfRangeException).

try
{
int[] numbers = { 1, 2, 3 };
int x = numbers[5]; // خطا: IndexOutOfRangeException
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine("آیندکس از محدوده خارج شد: " + ex.Message);
}
catch (NullReferenceException ex)
{
Console.WriteLine("آبجکت null است: " + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("یک خطای عمومی رخ داد: " + ex.Message);
}
این سوال از من پرسیده شده است  + 
آرایه مجموعه ای از نمونه های مربوط به هم از نوع value و یا reference است. سه نوع آرایه توسط C#پشتیبانی می شود: آرایه تک بعدی: شامل یک ردیف است. همچنین به عنوان آرایه برداری معروف است. آرایه چند بعدی: مستطیلی است و شامل سطرها و ستون ها است. آرایه ناهموار(Jagged): شامل سطرها و ستونها است اما شکل نامنظمی دارد.

آرایه ای که دارای عناصری از نوع آرایه باشد ، آرایه Jagged نامیده می شود. عناصر می توانند در ابعاد و اندازه های مختلف باشند. ما همچنین می توانیم آرایه Jagged را به عنوان آرایه ای از آرایه ها بنامیم.

ArrayList یک آرایه پویا است. در زمان اجرا می توانید عناصر را از ArrayList اضافه و حذف کنید. در ArrayList ، عناصر به طور خودکار مرتب نمی شوند.

در یک آرایه ، ما می توانیم مواردی از نوع یکسان را داشته باشیم. اندازه آرایه همواره ثابت است. arraylist شبیه به یک آرایه است اما اندازه ثابتی ندارد.

Interface یک نوع قرارداد (Contract) است که مشخص میکند یک کلاس چه متدهاو پراپرتی هایی را باید پیادهسازی کند، ولی خود Interface هیچ پیادهسازیای ندارد. در واقع Interface فقط امضا (Signature) تعریف میکند. کلاسهایی که این Interface را پیادهسازی کنند، موظفند همه متدها و Properties مشخص شده را بسازند. میتوانید بگویی Interface میگوید "چه کاری انجام بده"، نه "چطور انجام بده". نکات مهم: - یک کلاس میتواند چندین Interface را پیادهسازی کند. - Interface نمیتواند فیلد (Field) داشته باشد فقط پراپرتی دارد. - میتوان از Interface برای Polymorphism استفاده کرد. - پیادهسازی و منطق به کلاسها واگذار میشود. - همه متدها و پراپرتی های داخل اینترفیس Public هستند. در مثال زیر IShape میگوید: هر چیزی که شکل باشد، باید متد GetArea و GetPerimeter داشته باشد. هیچ کدی داخل Interface نیست. کلاس Rectangle همه متدهای IShape را پیادهسازی کرده، پس قرارداد رعایت شده.

//Interface
public interface IShape
{
double GetArea();
double GetPerimeter();
}
//Implement Interface
public class Rectangle : IShape
{
public double Width { get; set; }
public double Height { get; set; }
public double GetArea()
{
return Width * Height;
}
public double GetPerimeter()
{
return 2 * (Width + Height);
}
}
//Use the interface and class in code
IShape shape = new Rectangle { Width = 5, Height = 3 };
Console.WriteLine(shape.GetArea());
این سوال از من پرسیده شده است  + 
Lock برای اطمینان از این مساله استفاده میشود که چندین Thread همزمان در بخش حساس کد وارد نشوند. اگر Therad دیگری همزمان سعی کند که وارد بلوک کد Lock شود، مسدود می شود و منتظر میماند تا توکن آزاد شود. بدون Lock، دادههای مشترک ممکن است ناصحیح یا ناپایدار شوند. در کد زیر یک نمونه کد ملاحظه میکنید. آبجکت obj یک توکن است که هر Thread وقتی وارد بلوک کد Lock میشود آن را در دست میگیرد و این توکن فقط وقتی آزاد میشود که کار Thread فعلی با بلوک Lock تمام شود. بعد از آزاد شدن توکن Thread بعدی مجاز است وارد بلوک شود.

class Program
{
static object obj = new object();
static int counter = 0;
static void IncrementCounter()
{
for (int i = 0; i < 1000; i++)
{
lock (obj)
{
counter++;
}
}
}
static void Main()
{
Thread t1 = new Thread(IncrementCounter);
Thread t2 = new Thread(IncrementCounter);
t1.Start();
t2.Start();
t1.Join();
t2.Join();
Console.WriteLine(counter); // همیشه 2000
}
}
این سوال از من پرسیده شده است  + 
به فرآیند تبدیل یک شی به یک فرمت قابل ذخیره در فایل یا قابل ارسال در شبکه، Serlialization می گویند و به فرایندی که عمل عکس را انجام می دهد Deserialization می گویند. فرمت های پرکاربرد Binary، XML و Json می باشند.

//Serlialization
using System.Text.Json;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
var person = new Person { Name = "Ali", Age = 30 };
// تبدیل شیء به JSON
string json = JsonSerializer.Serialize(person);
Console.WriteLine(json);
// خروجی: {"Name":"Ali","Age":30}
//Deserlialization
// تبدیل JSON به شیء
Person p2 = JsonSerializer.Deserialize<Person>(json);
Console.WriteLine(p2.Name); // خروجی: Ali
Console.WriteLine(p2.Age); // خروجی: 30
این سوال از من پرسیده شده است  + 
موارد زیر modifier های دسترسی هستند که عموماً برای دسترسی استفاده می شوند: - public: اگر یک attribute یا متد را public تعریف کنید ، می توانید از هر جای کد پروژه به آن دسترسی داشته باشید. - private: به attribute یا متد تعریف شده خصوصی تنها می توان در داخل کلاس فعلی دسترسی داشت. - protected: اگر متد یا attribute را protected تعریف کنید ، می توانید از هر متدی در کلاسهای فرزند و هر متدی در همان کلاس به آن ها دسترسی داشته باشید. - internal: اگر یک ویژگی یا متدی را به عنوان internal تعریف کنید ، به کلاسهای موجود در assembly پروژه فعلی محدود می شود. - protected internal: اگر یک attribute یا متدی را به عنوان protected internal تعریف کنید ، دسترسی به کلاسهای موجود در assembly پروژه فعلی یا انواع مشتق شده از کلاس فعلی آن محدود می شود.

کلاس abstarct به غیر از متدهای abstract متدهای پیاده سازی شده نیز دارد ولی interface فقط شامل متدهای abstract میباشد. در interface همه متدها از نوع public هستند ولی در کلاس abstract میتوان متدهای private نیز داشت..

پارامترهای متد در overloading متفاوت ولی در overloading یکسان است. وراثت در overloading مورد نیاز نیست و در داخل یک کلاس overload های مختلف یک متد تعریف میشود ولی در overriding وراثت لازم است. یعنی کلاس فرزند میتواند متد تعریف شده در کلاس والد را override کند.

Delegate یک نوع داده خاص است که میتواند به یک یا چند متد اشاره کند. به عبارتی Delegate یک اشارهگر امن به متدها در C# است. نکات مهم - Delegate نوع امن است، یعنی نوع پارامترها و نوع بازگشتی Delegate باید با متد اشاره شده تطابق داشته باشد. - میتواند چند متد را به یک Delegate وصل کرد (Multicast Delegate). - پایهی Eventها در C# هستند: هر Event در واقع یک Delegate است. - Command از Delegate برای فراخوانی متد استفاده میکند( در سمپل کد آخر _execute در واقع یک Delegate است که Command نگه میدارد و هنگام Execute() صدا زده میشود). دلایل استفاده از Delegate: - Delegate باعث میشود چند متد بتوانند به یک Event گوش دهند و هنگام وقوع Event اجرا شوند. - گاهی میخواهیم متدی را به متد دیگر پاس دهیم تا بعداً اجرا شود. Delegate امکان این کار را میدهد. - Delegate باعث میشود کلاسها به متدهای مشخص وابسته نباشند. فقط امضای متد مهم است، نه خود متد. این باعث میشود برنامه انعطافپذیر و قابل تست باشد.

// تعریف Delegate
public delegate void MyDelegate(string message);
class Program
{
static void SayHello(string name)
{
Console.WriteLine($"سلام {name}!");
}
static void Main()
{
MyDelegate del = new MyDelegate(SayHello);
del("Ali");
}
}
-------------------------------------------------------------------------
//Events as Delegate
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
btn.Click += new RoutedEventHandler(UpdateText);
}
private void UpdateText(object sender, RoutedEventArgs e)
{
txt.Text = "Button Clicked!";
}
}
----------------------------------------------------------------------
//Delegate in Command
using System;
using System.Windows.Input;
public class RelayCommand : ICommand
{
private readonly Action _execute;
public RelayCommand(Action execute)
{
_execute = execute;
}
public bool CanExecute(object parameter) => true;
public void Execute(object parameter) => _execute();
public event EventHandler CanExecuteChanged;
}
این سوال از من پرسیده شده است  + 
یک آرگومان که به عنوان ref ارسال می شود باید قبل از انتقال به متد مقداردهی شود در حالی که پارامتر out قبل از انتقال به متد نیازی به مقداردهی اولیه ندارد.

در #C مدیریت حافظه به صورت خودکار توسط Garbage Collector انجام میگیرد، ولی با استفاده از بلوک کد using برنامه نویس میتواند به طور صریح کار تخصیص حافظه به اشیا و آزادسازی آن را انجام دهد. دستور using در واقع مرزی را برای استفاده از یک شی ایجاد میکند که خارج از آن آن شی به طور خودکار از بین می رود. برای فهم بهتر موضوع به مثال زیر دقت کنید. در این مثال شیئی به نام mnObj ایجاد شده است که در داخل بلوک کد using مورد استفاده قرار میگیرد. زمانی که به انتهای بلوک رسیدیم این شی از بین میرود و خارج از بلوک قابل استفاده نیست.

.......
using (MyManagedClass mnObj = new MyManagedClass())
{
......
mnObj.Use(); //use the mnObj object
......
} //The compiler will dispose the mnObj object now
......
این سوال از من پرسیده شده است  + 
خیر، در متدهای استاتیک (static) نمیتوانیم از this استفاده کنیم چون کلمهی کلیدی this همیشه به شیء جاری (Instance فعلی کلاس) اشاره میکند. متد استاتیک به یک شیء خاص تعلق ندارد، بلکه به خود کلاس تعلق دارد. وقتی شیئی وجود ندارد، طبیعتاً this هم وجود ندارد.

در C# هر دو const و readonly برای تعریف مقادیر ثابت و غیرقابلتغییر (Immutable) استفاده میشن، اما تفاوتهای کلیدی دارن: const: - مقدارش فقط موقع کامپایل مشخص میشه. باید همون لحظهی تعریف مقداردهی بشه. - فقط برای نوعهای primitive (مثل int, double, string, bool …) یا enum مناسبه. - به صورت پیشفرض static محسوب میشه (یعنی متعلق به خود کلاس هست نه نمونه). - چون در زمان کامپایل مقدار میگیره، سریعتره. readonly: - مقدارش میتونه موقع تعریف یا داخل سازنده (constructor) مقداردهی بشه. این یعنی مقدار در زمان اجرا (Runtime) هم میتونه مشخص بشه. - میتونه برای هر نوعی (حتی Reference Type مثل object, class, list, …) استفاده بشه. - لزوماً static نیست، ولی میتونی با static readonly ترکیبش کنی. - چون در زمان اجرا مقداردهی میشه، یک لایهی دسترسی بیشتر داره. به این معنی که باید بره از فیلد شیء یا کلاس مقدار رو بخونه. یعنی یه مرحله اضافه داره: برو سراغ شیء یا کلاس، مقدار رو از حافظه بردار و بعد نمایش بده.

متغییر Value Type معمولاً روی حافظه Stack ذخیره میشود. داده نیز مستقیماً در خود متغیر نگهداری میشود. متغیر Reference Type روی حافظه Stack قرار میگیرد، ولی مقدار در Heap ذخیره میشود. خود متغیر فقط یک آدرس به محل داده در Heap نگه میدارد. Struct، متغیرهای نوع Primitive شامل int, float, double, bool, char, decimal و enum جزو Value Type ها هستند. همهی انواع class string نوع object همچنین array و interface, delegate از نوع Reference Type هستند. در زمان انتساب (Assignment) مقدار متغییر Value Type به متغیر دیگر، داده مستقیماً کپی می شود. ولی در Reference Type فقط آدرس (Reference) کپی می شود. متغیر Value Type با اتمام اجرای متد، از Stack پاک می شود. ولی متغییر Reference Type وقتی هیچ ارجاعی به آن شیء انجام نشود، Garbage Collector حافظه تخصیص شده به آن را در Heap آزاد می کند.. متغییر Value Type به طور پیشفرض null نمیگیرد (مگر اینکه Nullable<T> یا ? استفاده بشه) ولی Reference Type به صورت پیش فرض می تواند null باشد.

// Value Type
int a = 10;
int b = a;
b = 20;
Console.WriteLine(a);
Output; 10
---------------------------------------------
// Reference Type
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1;
arr2[0] = 99;
Console.WriteLine(arr1[0]);
Output: 99
این سوال از من پرسیده شده است  + 
کلاس sealed کلاسی است که امکان وراثت از آن وجود ندارد. یعنی فرزندی ندارد.

System.String تغییر ناپذیر است. وقتی مقدار یک متغیر رشته ای از نوع System.String را تغییر می دهیم ، یک حافظه جدید به مقدار جدید اختصاص داده می شود و تخصیص حافظه قبلی آزاد می شود. System.StringBuilder به گونه ای طراحی شده است که دارای یک رشته متغیر باشد که در آن می توان عملیات مختلفی را بدون تخصیص مکان جداگانه حافظه برای رشته اصلاح شده انجام داد.

با استفاده از روش Clone ، یک آرایه جدید شامل همه عناصر موجود در آرایه اصلی ایجاد می کنیم. اما با استفاده از روش CopyTo، همه عناصر آرایه موجود در آرایه موجود دیگری کپی می شوند. هر دو روش یک کپی سطحی را انجام می دهند.

جنریک ها کلاس های قابل استفاده مجددی هستند که نوع داده ای فیلدها، پارمترها و یا مقدار برگشتی متدها آنها در زمان استفاده تعیین میشود. بنابراین آنها از تولید کد اضافه جلوگیری میکنند. یک کلاس جنریک به وسیله براکت های زاویه ای <> تعریف شود. برای مثال List یک کلاس جنریک است که می تواند هر نوع داده ای را بگیرد.

ArgumentException, ArgumentNullException, ArgumentOutOfRangeException, ArithmeticException, DivideByZeroException ,OverflowException, IndexOutOfRangeException, InvalidCastException, InvalidOperationException, IOEndOfStreamException , NullReferenceException, OutOfMemoryException, StackOverflowException.

کلاس را به صورت public تعریف کنید ولی متد را sealed تعریف کنید تا از override شدنش جلوگیری شود.

struct ها از نوع value-type هستند ولی کلاس ها از نوع reference-type هستند. struct ها روی حافظه Stack ذخیره می شوندکه باعث سربار اضافی میشود اما بازیابی سریعتر می شود. struct ها را نمی توان به ارث برد.

عملگر "is" برای بررسی یکی بودن نوع یک شی با یک نوع مشخص استفاده می شود و نتیجه را به صورت Boolean برمی گرداند. در حالی که عملگر "as" برای تبدیل نوع یک شیء به یک نوع یا کلاس دیگر استفاده می شود.

میتوانیم از طریق سازنده(Constructor) کلاس پدر به فیلدهای خصوصی آن دسترسی پیدا کرده و به آنها مقدار دهیم. به مثال زیر توجه کنید. در این مثال دو کلاس با نام های A و B وجود دارند که کلاس B فرزند کلاس A است و هر یک دارای یک فیلد خصوصی هستند. برای دسترسی به فیلد private_field_A از طریق سازنده کلاس B ، از دستور base با یک پارامتر ورودی استفاده میکنیم. با این روش ابتدا سازنده کلاس پدر فراخوانی شده و فیلد private_field_A مقدار value1 را می گیرد، سپس مقدار value2 به private_field_B تخصیص می یابد.

public class A
{
private int private_field_A;
public A(int value)
{
private_field= value;
}
}
public class B:A
{
private int private_field_B;
public B(int value1,int value2):base(value1)
{
private_field_B=value2;
}
}
این سوال از من پرسیده شده است  + 
برای اینکه بتوانیم متدی از کلاس پدر را در کلاس فرزند بازنویسی (override) کنیم ابتدا باید متد پایه در کلاس پدر virtual و یا abstract باشد. سپس باید جهت بازنویسی آن متد در کلاس فرزند در کنار نام متد از کلمه override استفاده کنیم. در زمان بازنویسی متدها در نظر داشته باشید که: - ساختار متد بازنویسی شده مانند تعداد پارامترها و نوع مقدار بازگشتی باید با متد پایه یکسان باشد. - شما نمیتوانید Access Modifier متد پایه را در متد بازنویسی شده تغییر دهید. مثلا نمیتوانید آن را از public به private تغییر دهید. - شما نمیتوانید یک متد ایستا (static) را بازنویسی کنید. به مثال زیر توجه کنید:

abstract class Shape
{
public abstract int GetArea();
}
class Square : Shape
{
private int _side;
public Square(int n) => _side = n;
// GetArea method is required to avoid a compile-time error.
public override int GetArea() => _side * _side;
static void Main()
{
var sq = new Square(12);
Console.WriteLine($"Area of the square = {sq.GetArea()}");
}
}
// Output: Area of the square = 144}
این سوال از من پرسیده شده است  + 
در سی شارپ از فضاهای نام برای مرتب کردن و سازماندهی منطقی کلاس ها، structها، interface ها، enumها و delegateها استفاده می شود. فضاهای نام در سی شارپ می توانند تودرتو باشند. این بدان معناست که یک فضای نام می تواند شامل فضاهای نام دیگری نیز باشد.

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

public sealed class SingletonClass {
private SingletonClass() {}
private static SingletonClass instance = null;
public static SingletonClass Instance {
get {
if (instance == null) {
instance = new SingletonClass();
}
return instance;
}
}
}
این سوال از من پرسیده شده است  + 
فرایند تبدیل نوع یک مقدار از value-type (بر روی حافظه Stack) به reference-type (بر روی حافظه Heap ) را Boxing و عکس این عمل را Unboxing می نامند. مثال:

int a=42;
object b=a; // Boxing
int c=(int)b;// Unboxing
این سوال از من پرسیده شده است  + 
خطاها در #C عموما بر دو نوع اند: 1) Run-time Errors: انواع Exceptionها که در زمان اجرای برنامه رخ میدهند و اجرای برنامه را متوقف میکنند، مانند خطای تقسیم بر صفر. 2) Compile-time Errors: مانند خطاهای نحوی (ُSyntax Errors)

حافظه Stack حافظهای سریع و کوچک است که برای ذخیرهی دادههای موقتی استفاده می شود. این داده ها شامل موارد زیر هستند: - متغیرهای محلی (Local variables). - پارامترهای متدها. - آدرس برگشت (Return address). - مقادیر نوعهای Value Type (مثل int, double, struct). مدیریت حافظه استک به صورت خودکار (LIFO = Last In, First Out) می باشد یعنی وقتی اجرای متدی تمام شد، همهی متغیرهای آن متد از Stack پاک میشوند. حافظه Heap حافظهی بزرگتر و کندتر است که برای ذخیرهی دادههای طولانیمدتتر استفاده میشود. در این حافظه داده های زیر ذخیره میشوند: - اشیاء (Objects) که از روی کلاسها ساخته میشن (new). - نوعهای Reference Type (مثل string, class, array, object). مدیریت حافظه پشته توسط Garbage Collector انجام میشه. وقتی دیگه هیچ ارجاعی (Reference) به یه شیء نباشه، GC اون رو آزاد میکنه.

1- اصل تک مسئولیت (Single Responsibility Principle - SRP): هر کلاس باید مسئولیت انجام یک کار مشخص را داشته باشد و تغییرات در یک کار، به ندرت باید باعث تغییراتی در سایر کارهاشود. این اصل به ایجاد کلاس های متمرکز و ماژولار کمک می کند که به نوبه خود باعث نگه داری، تغییر و درک آسانتر کد می شود. 2- اصل بازبینی مفهوم (Open/Closed Principle - OCP): یک کلاس باید برای توسعه باز اما برای تغییر بسته باشد.. به عبارت دیگر، کد باید برای افزودن ویژگیهای جدید باز باشد و از تغییر در کد موجود برای این کار خودداری شود. این اصل برنامه نویسان را به استفاده از ماژول های انتزاعی (Interface، Abstract class، Abstract method و ...) تشویق میکند تا بتوان عملکردهای جدیدی را بدون ایجاد تغییر در کد قبلی به برنامه اضافه کرد. 3- اصل جداسازی وابستگیها (Liskov Substitution Principle - LSP): این اصل بیان می کند که اشیاء یک زیرکلاس باید با اشیاء یک سوپرکلاس بدون تأثیر بر صحت برنامه قابل جایگزینی باشند. این اصل تضمین میکند که زیرکلاس ها به رفتار مورد انتظار از سوپرکلاس خود پایبند هستند و چندشکلی(Polymorphims) و قابلیت جایگزینی را ممکن میسازد. 4- اصل جدایی وابستگیها (Interface Segregation Principle - ISP): یک کلاس نباید مجبور به پیاده سازی متدهایی از یک اینترفیس باشد که به آنها نیازی ندارد. این اصل به ایجاد اینترفیس های کوچکتر و متمرکزتر، سبکتر شدن پیاده سازی کلاس ها و ماژولار شدن کد کمک می کند. 5- اصل اتحاد (Dependency Inversion Principle - DIP): این اصل دو قسمت دارد. اولاً، ماژولهای با سطوح بالاتر (مثلاً Business Logic) نباید به ماژولهای با سطوح پایینتر(مثلاً دیتابیس، فایلسیستم، API) وابسته باشندبلکه هر دو از طریق یک Interface یا Abstraction با هم ارتباط بگیرن. ثانیاً، اصول توالی برعکس باید برقرار باشد، یعنی از ابتداییترین ماژولها شروع شود و به سمت ماژولهای با سطوح بالاتر حرکت شود. این اصل تضمین میکند که در کد از پترن هایی مثل Debendency Injection، Inversion of Control و انتزاعات به کرات استفاده میشود تا به یک کد منعطفتر با وابستگی کمتر برسیم.

DI یک الگوی طراحی(Design Patern) است که در آن یک کلاس وابستگی های خود را از منابع خارجی دریافت می کند نه اینکه آنها را در داخل ایجاد کند. این الگو Loose Coupling را ترویج می کند و تست، نگهداری و توسعه کد شما را آسان تر می کند. در سی شارپ، یکی از راههای رایج برای پیادهسازی Dependency Injection، استفاده از Constructor Injection است. فرض کنید در کد شما سرویسی جهت لاگ گذاری برنامه اضافه شده است و شما میخواهید از این سرویس در یک کلاس استفاده کنید. نمونه کد این سرویس را در قسمت زیر مشاهده میکنید. ILogger اینترفیسی برای سرویس لاگ گذاری است. ConsoleLogger هم یک پیاده سازی از این سرویس است. ServiceWithLogger کلاسی از برنامه است که قصد دارد از سرویس لاگذاری استفاده کند. حال ما در این کد قصد داریم ILogger را به این کلاس تزریق کنیم. با اینکار شما وابستگی کلاس ServiceWithLogger را به هر کلاسی که ILogger را پیاده سازی کرده است از بین میبرید. این کار به ما کمک میکند که جایگزینی کلاس ConsoleLogger با هر پیاده سازی دیگری از اینترفیسILogger به راحتی امکان پذیر باشد. از طرفی این الگو به پیاده سازی اصل Dependency Inversion از الگوی SOLID نیز کمک میکند چون ماژول سطح بالای ServiceWithLogger به یک ماژول انتزاعی وابسته است تا به یک پیاده سازی واقعی.

using System;
// Logger interface
public interface ILogger
{
void Log(string message);
}
// Implementation of Logger
public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine($"Logging: {message}");
}
}
// Class that depends on ILogger through constructor injection
public class ServiceWithLogger
{
private readonly ILogger _logger;
// Constructor injection
public ServiceWithLogger(ILogger logger)
{
_logger = logger;
}
public void DoSomething()
{
// Some functionality
_logger.Log("Doing something...");
}
}
class Program
{
static void Main()
{
// Create an instance of the Logger
ILogger logger = new ConsoleLogger();
// Inject the logger into the ServiceWithLogger class
ServiceWithLogger service = new ServiceWithLogger(logger);
// Call a method on ServiceWithLogger, which internally uses the injected logger
service.DoSomething();
}
}
این سوال از من پرسیده شده است  + 
قوانین شیءگرایی (OOP Principles)همان اصول اصلی برنامهنویسی شیءگرا هستند که باعث میشوند کد ما ماژولار، قابلنگهداری و توسعهپذیر باشد. قوانین اصلی OOP: 1. Encapsulation (کپسولهسازی): یعنی مخفی کردن جزئیات پیادهسازی و فقط نمایش آنچه نیاز است. دادهها (فیلدها) معمولاً `private` نگه داشته میشوند و برای دسترسی به آنها از Property یا متد استفاده میکنیم 2. Abstraction (انتزاع ): یعنی تمرکز بر روی آنچه یک شی انجام میدهد، نه چطور انجام میدهد. برای این کار از Interfaceیا Abstract Class استفاده میکنیم. 3. Inheritance (وراثت): یعنی تعریف کلاس جدید بر اساس یک کلاس موجود. کلاس فرزند میتواند ویژگیها و رفتارهای کلاس والد را به ارث ببرد. 4. Polymorphism (چندریختی): یعنی یک متد میتواند در کلاسهای مختلف رفتار متفاوتی داشته باشد. به دو شکل هست: - Compile-time Polymorphism با Overloading - Runtime Polymorphism با Override و Virtual

//Encapsulation:
interface IDatabase
{
void Save(string data); // فقط تعریف عمل
}
class SqlDatabase : IDatabase
{
public void Save(string data)
{
Console.WriteLine("Save to SQL Database: " + data);
}
}
//Abstraction :
interface IDatabase
{
void Save(string data); // فقط تعریف عمل
}
class SqlDatabase : IDatabase
{
public void Save(string data)
{
Console.WriteLine("Save to SQL Database: " + data);
}
}
//Inheritance:
class Animal
{
public void Eat() => Console.WriteLine("Eating...");
}
class Dog : Animal
{
public void Bark() => Console.WriteLine("Barking...");
}
//Polymorphism:
class Animal
{
public virtual void Speak() => Console.WriteLine("Animal sound");
}
class Dog : Animal
{
public override void Speak() => Console.WriteLine("Woof!");
}
این سوال از من پرسیده شده است  + 
سوالی هست که اینجا نمیبینیش و از نظر تو مهمه؟ خودت سوالی داری که دنبال جوابشی؟ جواب بهتری واسه یکی از سوالای بالا داری؟ پس واسمون بفرست.
چه تفاوتی بین public ، static ...
Net. چیست؟
مزایای استفاده از NET. چیست؟
تفاوت بین Reference Type و Val...
برو به همه سوالات
WPF چیست؟
انواع اسناد پشتیبانی شده توسط ...
فضای نام مورد نیاز برای کار با...
آیا درست است که بگوییم WPF جای...
برو به همه سوالات