Immutable Collectionها در سیشارپ

👈 Immutable Collectionها در سیشارپ تغییرناپذیر هستند اما چرا باید یک کالکشن تغییرناپذیر به درد ما بخوره؟


👁 بازدید : 98

1402/12/28 | 23:14 : تاریخ 📆


 تعریف Immutability یا تغییر ناپذیری :

اصولا در برنامه نویسی شی گرا هر متغییر،پراپرتی،کلاس و کلا هرچیزی که لازمه تغییر ناپذیر باشه رو Immutable میگن،حالا این تغییر ناپذیری رو ما در لیست ها هم از سیشارپ 9 به بعد شاهد هستیم.

کد زیر رو در نظر داشته باشید:

class Program
{
   static List<int> numberList = new List<int>{1,2,3,4,5};
  static void Main(string[] args)
  {
    numberList = new List<int>{9,8,7};
    numberList[0] = -1;
    numberList.Add(14);
    numberList.Remove(3);
  }
}

کاملا واضح هست که یک لیست اینتیجر داریم و در بدنه main هم میتونیم اینیشیلایز کنیم و هم میتونیم مقادیر خونه هاشو تغغیر بدیم یا حذف کنیم.

اما یک سوال : چه کار باید بکنیم تا بعدا نتونیم دیتاهارو تغییر بدیم و از این کار جلوگیری کنیم؟

فقط کافیه کلمه read only رو اضافه کنیم  static readonly List<int> numberList = new List<int>{1,2,3,4,5}

 read only یعنی ما فقط میتونیم یک بار مقدار دهی کنیم و بعد از روش بخونیم،حالا مقداردهی میتونه یک valueایی باشه یا یک آبجکت یا هر چیز دیگه...

اما با این حال هنوز میتونیم خونه های لیست رو تغییر بدیم یا اونو حذف کنیم.دقیقا اینجاست که Immutable Collection وارد بازی میشن.

class Program
{
  static readonly ImmutableList<int> numberList = new List<int>{1,2,3,4,5}.ToImmutableList();
  static void Main(string[] args)
  {
    numberList = new List<int>{9,8,7}; //we have error this line
    numberList[0] = -1;                //we have error this line
    numberList.Add(14);
    numberList.Remove(3);
  }
}

در کد بالا به محض اینکه List به ImmutableList تغییر میکنه ما دیگه نمیتونیم خونه های لیست رو تغییر بدیم.پس اگر بخواهید خونه صفرم لیست رو تغییر بدید! عمراً، اصلا فکرشم نکنید، چون شما رو حالت ImmutableList هستید. اما همچنان add و remove کارایی خودشون رو دارن. درواقع یک ImmutableList تمام کارایی های یک List رو داره اما ساختارش، یک ساختار درختی میشه. به کد زیر دقت کنید:

var list1 = ImmutableList.Create<int>(); 
var list2 = list1.Add(1);
var list3 = list2.Add(3);
var list4 = list3.Add(5);
var list5 = list4.Add(7);

همینطور که میبینید list5 داره مقدارشو از لیست های قبلی میگیره(شما بخواننید گره) و لیست های قبلی هم هر کدوم از لیست قبلتر و این طور یک ساختار درختی در این کالکشن بوجود میاد.توجه داشته باشید که list1 یک لیست خالی را برمیگرداند که یک سینگلتون است.

list1 --> empty

list2 --> list1  ,  1  

list3 --> list1 , list2 ,  3 

list4 --> list1 , list2 ,  list3 ,  5 

list5 --> list1 , list2 ,  list3 , list4 ,  7 

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

var list6 = list5.Replace(7,40);

با این حال تمام لیست های جنریک قابلیت Immutable بودن رو دارن و خصوصیت ذکر شده بالا برای تمام کالکش های Immutable یکی هست.

این مقاله بزودی بروزرسانی میشود...

 تعریف Immutability یا تغییر ناپذیری :

اصولا در برنامه نویسی شی گرا هر متغییر،پراپرتی،کلاس و کلا هرچیزی که لازمه تغییر ناپذیر باشه رو Immutable میگن،حالا این تغییر ناپذیری رو ما در لیست ها هم از سیشارپ 9 به بعد شاهد هستیم.

کد زیر رو در نظر داشته باشید:

class Program
{
   static List<int> numberList = new List<int>{1,2,3,4,5};
  static void Main(string[] args)
  {
    numberList = new List<int>{9,8,7};
    numberList[0] = -1;
    numberList.Add(14);
    numberList.Remove(3);
  }
}

کاملا واضح هست که یک لیست اینتیجر داریم و در بدنه main هم میتونیم اینیشیلایز کنیم و هم میتونیم مقادیر خونه هاشو تغغیر بدیم یا حذف کنیم.

اما یک سوال : چه کار باید بکنیم تا بعدا نتونیم دیتاهارو تغییر بدیم و از این کار جلوگیری کنیم؟

فقط کافیه کلمه read only رو اضافه کنیم  static readonly List<int> numberList = new List<int>{1,2,3,4,5}

 read only یعنی ما فقط میتونیم یک بار مقدار دهی کنیم و بعد از روش بخونیم،حالا مقداردهی میتونه یک valueایی باشه یا یک آبجکت یا هر چیز دیگه...

اما با این حال هنوز میتونیم خونه های لیست رو تغییر بدیم یا اونو حذف کنیم.دقیقا اینجاست که Immutable Collection وارد بازی میشن.

class Program
{
  static readonly ImmutableList<int> numberList = new List<int>{1,2,3,4,5}.ToImmutableList();
  static void Main(string[] args)
  {
    numberList = new List<int>{9,8,7}; //we have error this line
    numberList[0] = -1;                //we have error this line
    numberList.Add(14);
    numberList.Remove(3);
  }
}

در کد بالا به محض اینکه List به ImmutableList تغییر میکنه ما دیگه نمیتونیم خونه های لیست رو تغییر بدیم.پس اگر بخواهید خونه صفرم لیست رو تغییر بدید! عمراً، اصلا فکرشم نکنید، چون شما رو حالت ImmutableList هستید. اما همچنان add و remove کارایی خودشون رو دارن. درواقع یک ImmutableList تمام کارایی های یک List رو داره اما ساختارش، یک ساختار درختی میشه. به کد زیر دقت کنید:

var list1 = ImmutableList.Create<int>(); 
var list2 = list1.Add(1);
var list3 = list2.Add(3);
var list4 = list3.Add(5);
var list5 = list4.Add(7);

همینطور که میبینید list5 داره مقدارشو از لیست های قبلی میگیره(شما بخواننید گره) و لیست های قبلی هم هر کدوم از لیست قبلتر و این طور یک ساختار درختی در این کالکشن بوجود میاد.توجه داشته باشید که list1 یک لیست خالی را برمیگرداند که یک سینگلتون است.

list1 --> empty

list2 --> list1  ,  1  

list3 --> list1 , list2 ,  3 

list4 --> list1 , list2 ,  list3 ,  5 

list5 --> list1 , list2 ,  list3 , list4 ,  7 

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

var list6 = list5.Replace(7,40);

با این حال تمام لیست های جنریک قابلیت Immutable بودن رو دارن و خصوصیت ذکر شده بالا برای تمام کالکش های Immutable یکی هست.

این مقاله بزودی بروزرسانی میشود...

🗨️دیدگاه‌ها


Immutable Collectionها در سیشارپ

هنوز دیدگاهی ثبت نشده

تمامی‌حقوق‌مادی‌ومعنوی‌این‌سایت‌برای‌یادمیگیریم‌محفوظ است.