value type و refrence type ها چی هستند؟ - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

value type و refrence type ها چی هستند؟

+2 امتیاز
لطفا در مورد value type و refrence type  یک توضیح بدین که اصلا برای چی وجود دارن توی سی شارپ و کاربردشون چی هست؟ و یک مثال .
سوال شده اسفند 16, 1392  بوسیله ی daniyaltjm (امتیاز 840)   47 88 103
ویرایش شده اسفند 16, 1392 بوسیله ی مصطفی ساتکی

1 پاسخ

+4 امتیاز
 
بهترین پاسخ

سلام.

ما در حالت کلی دو نوع از داده ها رو داریم. یکی value type ها مثل int  و string و ... و نوع دوم reference type ها مثل آرایه ها []int ، کلاس ها، جنریک ها و ...

اما فرق این ها چیه. در مورد value type ها برای هر متغیری که تعریف می کنید یک فضای واحد و مجزا در حافظه سریع استک براشون در نظر گرفته میشه. مشخصه این مدل نوع داده ای اینه که برای ایجاد شدن نیازی به new کردن ندارند ( بر خلاف نوع داده ای reference type ها که در حافظه heap ساخته میشن و در واقع با new کردن ایجاد میشن).

در نوع داده ای reference type ما با آدرس ها سر و کار داریم. این آدرس در استک قرار می گیره و بعد این آدرس به متغیر ما که در heap قرار داره  اشاره میکنه در صورتیکه در value type مقدار مستقیما در استک قرار می گیره.

در value type ها همونطور که گفتم خانه های حافظه تخصیص داده شده به متغیرها کاملا مجزا هستن. این به این معنی هستش که اگر یک متغیر دستخوش تغییر بشه تاثیری بر روی مقادیر سایر متغیرها نداره ولی در Reference type ها اگر آدرسی که چند متغیر به اون اشاره میکنن، مقدارش دچار تغییر بشه، همه اون متغیرها مقدارشون عوض میشن. این مطلب اخر رو با یک مثال توضیح میدم تا نحوه کار مشخص بشه (حتما اینو در کامپیوترتون تست کنید) :

برای value type ها :

در این مثال، دو متغیر int که value type هستن به نام های i و j ساخته شدن و مقدار متغیر i رو درون j ریختیم و اونها رو چاپ کردیم. بعدش مقدار i رو تغییر دادیم و دوباره متغیرهای i و j رو چاپ کردیم. خواهید دید فقط مقدار i تغییر میکنه و j همون مقدار اولیه رو خواهد داشت. این بخاطر اینه که i  و j دو خونه کاملا مستقل از همدیگه رو دارند و تغییر در یکی بر روی دیگری تاثیری نداره و هر خانه حافظه (متغیر) برای تغییر مقدارش، باید مستقیما دستخوش تغییر بشه.

            int i = 20;
            int j = i;
            Console.WriteLine(i);
            Console.WriteLine(j);
            i = 25;
            Console.WriteLine(string.Format("new i is : {0}", i));
            Console.WriteLine(string.Format("new j is : {0}", j));
            Console.ReadKey();

مثالی برای Reference type ها :

در این مثال، ما دو آرایه که از جنس Reference Type ها هستن ایجاد کردیم و بعد مقدار آرایه اول رو درون آرایه دوم ریختیم  و در ادامه اقدام به چاپ مقادیر این آرایه ها کردیم.

بعد از چاپ، تنها کاری که انجام دادیم اینه که مقادیر آرایه اول رو تغییر دادیم و دوباره مقادیر هر دو آرایه رو چاپ کردیم. نتیجه جالب خواهد بود. با وجود اینکه ما مقادیر آرایه دوم رو هیچگونه دستکاری نکردیم ولی مقادیر دقیقا همون چیزی خواهند بود که در آرایه اول وجود دارند. این بخاطر همون بحث آدرس هست. وقتی ما آرایه اول رو با new کردن ایجاد می کنیم درون استک آدرسی ساخته میشه و به جایی اشاره میشه (حافظه heap) که مقادیر آرایه (همون 1 و 2 و 3) اونجا نگهداری میشن. وقتی آرایه اول رو به آرایه دوم نسبت می دیم، برای آرایه دوم هم دقیقا همون آدرس ایجاد میشه. یعنی جفتشون دارن به یک آدرس اشاره میکنن و زمانیکه اون مقادیر تغییر میکنن (تغییر مقادیر آرایه اول به 4 و 5 و 6)، آرایه دوم هم که داره به همون آدرس اشاره میکنه مقادیرش دستخوش تغییر میشه.

امیدوارم مطلب براتون جا افتاده باشه.

موفق باشید.

int[] array1 = new int[] { 1, 2, 3 };
            int[] array2 = new int[3];
            array2 = array1;
            Console.Write("array1 is : ");
            foreach (int i in array1)
            {
                Console.Write(string.Format("{0}  ",i)); 
            }
            Console.Write("array2 is : ");
            foreach (int j in array2)
            {
                Console.Write(string.Format("{0}  ", j));
            }
            array1[0] = 4;
            array1[1] = 5;
            array1[2] = 6;
            Console.Write("\n array1 after change is : ");
            foreach (int m in array1)
            {
                Console.Write(string.Format("{0}  ", m));
            }
            Console.Write("array2 after change is : ");
            foreach (int n in array2)
            {
                Console.Write(string.Format("{0}  ", n));
            }
            Console.ReadKey();

 

پاسخ داده شده اسفند 16, 1392 بوسیله ی veniz2008 (امتیاز 2,083)   1 5 21
انتخاب شد اسفند 16, 1392 بوسیله ی daniyaltjm
...