PDA

View Full Version : استفاده بیش از حد از شی نمونه



aminkk
جمعه 01 خرداد 1388, 13:45 عصر
سلام بر دوستان
بچه ها من اکثر کدهای برنامه ها رو که میبینم اکثرا میان شی نمونه در حافظه درست می کنن.چرا C# اینجوری هستش؟چون شما ببینید برای هر کاری باید شی نمونه بسازیم(البته نه همه جا)

مثلاً منی که اماتورم از کجا بفهمم که باید برای فلان کار باید شی نمونه در حافظه بسازم؟شاید جواب این باشه: باید انواع refrence رو بلد باشید.اما از کجا بفهمیم که یک شی از نوع refrence هست یا value؟

linux
جمعه 01 خرداد 1388, 13:57 عصر
سلام بر دوستان
بچه ها من اکثر کدهای برنامه ها رو که میبینم اکثرا میان شی نمونه در حافظه درست می کنن.چرا C# اینجوری هستش؟چون شما ببینید برای هر کاری باید شی نمونه بسازیم(البته نه همه جا)

مثلاً منی که اماتورم از کجا بفهمم که باید برای فلان کار باید شی نمونه در حافظه بسازم؟شاید جواب این باشه: باید انواع refrence رو بلد باشید.اما از کجا بفهمیم که یک شی از نوع refrence هست یا value؟
تمام کلاس ها رفرنس تایپ هستند
استراکچرها ولیو تایپ هستند
استرینگ و اعداد هم ولیو تایپ هستند

Mahdi.Kiani
جمعه 01 خرداد 1388, 14:48 عصر
استرینگ و اعداد هم ولیو تایپ هستند
استرینگ reference type هست نه value type





........Although string is a reference type


read more (http://msdn.microsoft.com/en-us/library/362314fe%28VS.80%29.aspx)

prankster
جمعه 01 خرداد 1388, 20:59 عصر
استرینگ reference type هست نه value type


دقیقا، گرچه پیاده سازی کلاس string در Net. به گونه ای است که بیشتر شبیه value type به نظر می آید، برای مثال مقدار بازگشتی اپراتور == در مورد نمونه های string با value های یکسان برابر true است.

سوال اینجاست که چرا هنگامی که مثلا متغیر از جنس string برای یک تابع ارسال می شود و در آن تابع تغییر می کند، متغیر اصلی در routine اصلی تغییر نمی کند؟


static void Main(string[] args)
{
string s1 = "Hello";
SomeMethod(s1);
Console.WriteLine(s1);
}

static void SomeMethod(string a)
{
a += " there";
Console.WriteLine(a);
}


جواب این سوال اینجاست که نمونه های کلاس string غیر قابل تغییر هستند، بدین صورت که تنها هنگام ایجاد می توانند مقدار بگیرند، بعد از ایجاد با هر بار تغییر نمونه کلاس string عملا object دیگری از کلاس ایجاد می شود. چند دقیقه پیش عملا این مساله را تست کردم، نتیجه خیلی جالب است:




static void Main(string[] args)
{
var s1 = "Hello";
var s2 = s1;

Console.WriteLine(s1.GetHashCode().ToString());
Console.WriteLine(s2.GetHashCode().ToString());

s1 += " there";

Console.WriteLine(s1.GetHashCode().ToString());
Console.WriteLine(s2.GetHashCode().ToString());
}

هر بار تغییر متغیر از جنس string شیئ کاملا جدیدی را در حافظه بارگزاری می کند و فکر می کنم در صورتی که refrence دیگری به شیئ قبلی وجود نداشته باشد آن شیئ garbage collect می شود.

Mahdi.Kiani، سوالی که برای من بوجود آمده است ان است که هنگامی که از ref یا out برای refrence دادن به متغیر از جنس string استفاده می کنیم عملا چگونه مقدار string تغییر می کند در صورتی که کلاس string غیر قابل تغییر تعریف شده است؟!


static void Main(string[] args)
{
var s1 = "Hello";

Console.WriteLine(s1.GetHashCode().ToString());

SomeMethod(ref s1);

Console.WriteLine(s1.GetHashCode().ToString());
}

static void SomeMethod(ref string someString)
{
someString += " there";
Console.WriteLine(someString.GetHashCode().ToStrin g());
}

در مثال بالا متغیر s1 تغییر کرده است، در صورتی که s1 قبل و بعد از صدا زدن متد به آدرس مشابهی در hash table اشاره می کند!