گفتگو هایی در باب سی شارپ

the_king

مدیرکل انجمن
الان پس منظورتون اینه که با متدی از شی ای که از کلاس TreeView ساختم (یعنی شی treeViewName در اینجا) ، یه متدی استفاده کنم که اون TreeNode هایی که توی این شی داره رو برگردونه و خروجی اون TreeNode رو در ورودی این آرگومان بکار ببرم تا مثل کد در پست بالا که دادم ، شی جدیدی از TreeNode ها نسازم؟
متاسفانه اصلا متوجه منظورتون از این پاراگراف نمیشم، خلاصه حرفی که من زدم اینه، Contains رو برای شیء بکار ببرید که قبلا ساخته شده و ممکنه در مجموعه باشه یا نباشه، برای شیء جدیدی که با new می سازید بکار نبرید چون هیچوقت در اون مجموعه نخواهد بود، مگر در یک حالت های کاملا خاص، مثلا زمانی که کلاس اون شیء خاص برای Contains یک پیاده سازی اختصاصی انجام داده باشه.
بهترین کار برای دریافت TreeNode ها هم استفاده از همون حلقه ی foreach هه؟
foreach پیمایش می کنه، این کار دریافت نیست، اگر میخواهید به هر دلیلی گره ها را تک به تک پیمایش کنید foreach مناسبه وگرنه اگه منظورتون داشتن تمامی گره ها در یک آرایه است foreach برای این منظور نیست، متد CopyTo رو بکار ببرید. قبلا یک آرایه بطول مناسب می سازید و بعد محتویات اش رو با CopyTo پر می کنید. اغلب مجموعه ها متد CopyTo یا ToArray را دارند، اگر جایی نبود ناچارید از foreach استفاده کنید ولی معمولا هست.
البته یه متدی نیست که یه شی درخت رو بدیم و خودش برامون تمام Node های پرنت و child رو تا آخر پیدا کنه؟
همچین متدی می تونه با ترتیبهای مختلفی گره ها رو برگردونه، مثل همون مباحث پیمایش درخت در ساختمان داده، به همین جهت به هر شیوه ای که پیاده سازی بشه کاربرد محدودی خواهد داشت.
معمولا متد های کم کاربرد و محدود رو در کتابخانه های اصلی زبان قرار نمی دهند، بیخودی حجم Framework زیاد میشه. هر برنامه نویسی میتونه با چند خط کد ساده پیاده سازیش کنه.
اگر برای هیچکدوم از گره ها Name در نظرنگرفته اید، می توانید با همون Find دنبال گره هایی با کلید "" و پارامتر دوم true بگردید، همه گره ها و زیرگره ها را لیست خواهد کرد.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام . ممنون استاد علی
میگم هیچ راهی وجود نداره که یه آرایه را بصورت value type به متدی ارسال کرد . درسته؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
یه سئوال دیگه
فرق این دو تا چی هست؟ :


کد:
Form Form2 = new Form1();

و

کد:
Form1 Form2 = new Form1();

هر دو انگار مقدار Form1 رو میریزه توی شی Form2
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام
آقا علی ، ما اگه توی لوا یه متغییر محلی مثل زیر تعریف میکردیم ، بعد از بلاک داخلی ، دوباره مقدارش به اول خودش که قبل از بلاک تعریف شده بود برمیگشت یعنی در کد زیر اگه در لوا تعریف میشد ، داخل بلاک ، مقدار localNumber برابر 5 و بعد از بلاک مقدارش برابر 100 میشد . مثل دقیقا قضیه ی ارجاع با مقدار در آرگومان یک متد
این قضیه توی سی شارپ قابل اجرا نیست؟ :


کد:
int localNumber = 100;
            {
                localNumber = 5;
                MessageBox.Show("" + localNumber);
            }
            MessageBox.Show("" + localNumber);
 

the_king

مدیرکل انجمن
سلام . ممنون استاد علی
میگم هیچ راهی وجود نداره که یه آرایه را بصورت value type به متدی ارسال کرد . درسته؟
این قاعده کلی خیلی از زبان ها است که داده های آرایه ای و اشیاء reference type ارسال می شوند.

یه سئوال دیگه
فرق این دو تا چی هست؟ :


کد:
Form Form2 = new Form1();

و

کد:
Form1 Form2 = new Form1();

هر دو انگار مقدار Form1 رو میریزه توی شی Form2
داده شیء از یک نوع ئه، هر دو Form1 اند، ولی کامپایلر متغیر رو از دو نوع متفاوت در نظر می گیره، فرضا اگر Form1 یک متد public تعریف کرده باشید در متغیر از نوع Form بهش دسترسی ندارید چون Form همچین متدی نداره، برای اینکه کامپایلر رو متوجه کنید ناچار می شوید Type Casting کنید.

سلام
آقا علی ، ما اگه توی لوا یه متغییر محلی مثل زیر تعریف میکردیم ، بعد از بلاک داخلی ، دوباره مقدارش به اول خودش که قبل از بلاک تعریف شده بود برمیگشت یعنی در کد زیر اگه در لوا تعریف میشد ، داخل بلاک ، مقدار localNumber برابر 5 و بعد از بلاک مقدارش برابر 100 میشد . مثل دقیقا قضیه ی ارجاع با مقدار در آرگومان یک متد
این قضیه توی سی شارپ قابل اجرا نیست؟ :


کد:
int localNumber = 100;
            {
                localNumber = 5;
                MessageBox.Show("" + localNumber);
            }
            MessageBox.Show("" + localNumber);
نه، این کد مشابهی در #C و یا زبان های نزدیک به اون نداره.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
ممنون استاد علی
میگم این پنجره ای که مثلا موس رو روی آیکون های در system tray میبریم (مثل آیکون internet download manager و ...) ، توضیحاتی نمایش داده میشن رو popup windows میگن؟
اگه نه ، اسمش چیه؟
و اینکه همچین پنجره ای رو در سی شارپ چجوری میشه آورد؟
انگار توی سی شارپ یه همچین کنترلی ای طراحی نشد که ازش شی بسازیم . درسته؟! باید خودمون این پنجره رو طراحی کنیم؟
اگه آره ، نحوه ی طراحی باید این طور باشه که caption ویندوز دکمه های بستن و ماکسیمایز و ... رو برداریم و وقتی هم که این پنجره رو نمایش دادیم ، بلافاصله فوکوس برگرده به فرم اصیلی مون و وقتی هم که موس رو از روی شی و کنترلی که باعث ایجاد این پنجره شد ، دور کردیم ، این پنجره بسته شه؟
 

the_king

مدیرکل انجمن
ممنون استاد علی
میگم این پنجره ای که مثلا موس رو روی آیکون های در system tray میبریم (مثل آیکون internet download manager و ...) ، توضیحاتی نمایش داده میشن رو popup windows میگن؟
اگه نه ، اسمش چیه؟
و اینکه همچین پنجره ای رو در سی شارپ چجوری میشه آورد؟
انگار توی سی شارپ یه همچین کنترلی ای طراحی نشد که ازش شی بسازیم . درسته؟! باید خودمون این پنجره رو طراحی کنیم؟
اگه آره ، نحوه ی طراحی باید این طور باشه که caption ویندوز دکمه های بستن و ماکسیمایز و ... رو برداریم و وقتی هم که این پنجره رو نمایش دادیم ، بلافاصله فوکوس برگرده به فرم اصیلی مون و وقتی هم که موس رو از روی شی و کنترلی که باعث ایجاد این پنجره شد ، دور کردیم ، این پنجره بسته شه؟
دو جور پنجره است، یکی اون پنجره هایی که مثل منو و یا ComboBox ازشون گزینه انتخاب میشه و دومی اون پنجره هایی که صرفا یک بالن توضیحات یا Tooltip رو نشون میده. گروه دوم به هیچ وجه کاری با Focus و Caption ندارند.
نمایش بالن توضیحات نباید Focus رو بگیره چون تو کاری که کاربر انجام میداد اخلال ایجاد می کنه. بالن های Notification که در System Tray می بینید با کنترل استاندارد NotifyIcon ساخته می شوند.

مثال ییوستی رو ببینید.
 

پیوست ها

  • TooltipSample2.zip
    60.4 کیلوبایت · بازدیدها: 3

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
دو جور پنجره است، یکی اون پنجره هایی که مثل منو و یا ComboBox ازشون گزینه انتخاب میشه و دومی اون پنجره هایی که صرفا یک بالن توضیحات یا Tooltip رو نشون میده. گروه دوم به هیچ وجه کاری با Focus و Caption ندارند.
نمایش بالن توضیحات نباید Focus رو بگیره چون تو کاری که کاربر انجام میداد اخلال ایجاد می کنه. بالن های Notification که در System Tray می بینید با کنترل استاندارد NotifyIcon ساخته می شوند.

مثال ییوستی رو ببینید.

واقعا ممنونم ازتون استاد علی که به سئوالاتم جواب میدین . نمیدونم چجوری تشکر کنم :rose:
بعد از نوشتن متن ، فهمیدم اسمش همون tooltip ای هه که گفتین (البته قبلا میدونستم ولی با اسم popup قاتی کردم :))
بعد اینکه کلاس FixedToolTip چیه؟ انگار راحت تر از کلاس ToolTip هه . البته برای من چون کلاس ToolTip که متد Show اش اینترفیس میخواد و بلد نیستم باهاش کار کنم ، راحت تره

یه نکته ای خواستم بگم ، ببینین درسته؟ :
اینکه هر کلاسی از کلاس دیگه ای ارث ببره ، میشه شی ای (یا مقداری) از اون کلاس فرزند رو داخل متغییری (شی ای) از نوع کلاس پدر ریخت . درسته؟
واسه ی همینه توی پروژه ای که در بالا دادین ، در متد Form1_Load و در خط دوم اش ، در آرگومان سوم متد سازنده ی FixedTooltip ، که شی ای از Image میخواد ، بجاش ، شی ای از کلاس Bitmap دادین . پس میشه نتیجه گرفت که کلاس Bitmap فرزند یا نوادگان کلاس Image هست دیگه؟
و واسه ی همینه که مثلا میتونیم این جوری بنویسیم حلقه مون رو (فرضا اینکه فرم ما حاوی button ها و ... باشه) :

کد:
foreach (Control item in this.Controls)
            {

            }
که هر نوع کنترل مثل دکمه و لیبل و ... در داخل فرم رو داخل شی item که از نوع کنترل هست میریزه پس نتیجه میگیریم که کلاس Control ، والد کلاس هایی که توش قرار میگیرن هستن


درباره ی اینترفیس ها اگه زحمتی نیست یه لینک یا یه توضیح مختصر میدین و اینکه چجوری باید متد tooltip.show اون آرگومان دوم اش که اینترفیس میخواد رو مقداردهی کرد؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
آو !!
من sender رو به کنترل تبدیل کردم به عنوان پارامتر دوم متد show در tooltip که یه اینترفیس از IWin32Windows رو میخواد ، کار کرد و اشکالی نگرفت!!
چرا؟ اینترفیس اصلا چیه که وقتی از یه کلاس دیگه و متفاوت بهش میدن ، مشکلی نیست؟ مگه مثل قضیه ی همون ارث بری و والد و فرزند هه؟
من اینو نوشتم توی رویداد MouseEnter یه دکمه :

کد:
toolTip1.Show("salam", (Control)sender);
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
اینو نوشتم ، اما چرا تولتیپ ام سوسو میزنه؟ :

کد:
private void btnCreateCircle_MouseEnter(object sender, EventArgs e)
        {
            toolTip1.Show("Add Circle To GroupBox Test Control", btnCreateCircle);
           
        }

        private void btnCreateCircle_MouseLeave(object sender, EventArgs e)
        {
            toolTip1.Hide((Button)sender); 
        }

        private void btnCreateCircle_MouseMove(object sender, MouseEventArgs e)
        {
            toolTip1.Show("Add Circle To GroupBox Test Control", btnCreateCircle, e.Location);
        }

به نظر میاد مشکل از رویداد btnCreateCircle_MouseMove باشه اما چه مشکلی؟!
 

the_king

مدیرکل انجمن
واقعا ممنونم ازتون استاد علی که به سئوالاتم جواب میدین . نمیدونم چجوری تشکر کنم :rose:
بعد از نوشتن متن ، فهمیدم اسمش همون tooltip ای هه که گفتین (البته قبلا میدونستم ولی با اسم popup قاتی کردم :))
بعد اینکه کلاس FixedToolTip چیه؟ انگار راحت تر از کلاس ToolTip هه . البته برای من چون کلاس ToolTip که متد Show اش اینترفیس میخواد و بلد نیستم باهاش کار کنم ، راحت تره
کلاس FixedToolTip رو که من نوشتم، ربطی با Tooltip استاندارد ویندوز نداره.
یه نکته ای خواستم بگم ، ببینین درسته؟ :
اینکه هر کلاسی از کلاس دیگه ای ارث ببره ، میشه شی ای (یا مقداری) از اون کلاس فرزند رو داخل متغییری (شی ای) از نوع کلاس پدر ریخت . درسته؟
واسه ی همینه توی پروژه ای که در بالا دادین ، در متد Form1_Load و در خط دوم اش ، در آرگومان سوم متد سازنده ی FixedTooltip ، که شی ای از Image میخواد ، بجاش ، شی ای از کلاس Bitmap دادین . پس میشه نتیجه گرفت که کلاس Bitmap فرزند یا نوادگان کلاس Image هست دیگه؟
و واسه ی همینه که مثلا میتونیم این جوری بنویسیم حلقه مون رو (فرضا اینکه فرم ما حاوی button ها و ... باشه) :
کد:
foreach (Control item in this.Controls)
            {

            }
که هر نوع کنترل مثل دکمه و لیبل و ... در داخل فرم رو داخل شی item که از نوع کنترل هست میریزه پس نتیجه میگیریم که کلاس Control ، والد کلاس هایی که توش قرار میگیرن هستن
اگر وارث اون کلاس باشند که کاملا درسته، برای مثال هایی که زدید هم درست هست، ولی برای نتیجه گیری کافی نیست. Bitmap واقعا وارث Image هست، اما صرفا از اینکه دیدید در پارامتری این حالت وجود داره نباید نتیجه بگیرید که وارث شه، مادامی که تعریف کلاس اش رو ندیدید همچین نتیجه ای نمی توانید بگیرید که وارث اش هست یا نه. در تعریف هر کلاسی می توانید قابلیت تبدیل implicit به یک کلاس دیگه رو پیاده سازی کنید، فرضا اشیاء کلاس Class1 رو بدون هیچ مشکلی به Bitmap تبدیل کنید، ولی این بدین معنی نیست که Class1 وارث Bitmap ئه یا باهاش سازگاره. اون implicit operator به کامپایلر نشون میده که چطور یه شی Class1 رو به Bitmap تبدیل کنه، کامپایلر هم طبق اون تعریف هیچ خطا یا اخطاری برای همچین تبدیلی نشون نمیده اما این ظاهر قضیه است، Class1 کلا هیچ تناسبی با ساختار Bitmap نداره.
کد:
    class Class1
    {
        public static implicit operator Bitmap(Class1 a)
        {
            return new Bitmap(16, 16);
        }
    }

            Bitmap b = new Class1();

درباره ی اینترفیس ها اگه زحمتی نیست یه لینک یا یه توضیح مختصر میدین و اینکه چجوری باید متد tooltip.show اون آرگومان دوم اش که اینترفیس میخواد رو مقداردهی کرد؟
قبلا صحبتش رو کردیم، اینترفیس تعریف ساختار بدون پیاده سازی ئه، مثل کلاسی است که مشخصات متد ها در اون تعریف شده اند ولی ابدا پیاده سازی نشده اند. مثل کلاس وراثت داره و در ضمن مجبورتون هم می کنه که تک تک اون متد های اینترفیس رو پیاده سازی کنید چون خود اینترفیس هیچ پیاده سازی براشون نداره که بخواهید از پیاده سازی صرف نظر کنید. شما شیء از هر کلاسی که از IWin32Window ارث بری کرده مثل Control رو بهش تحویل بدهید قبوله.
اینو نوشتم ، اما چرا تولتیپ ام سوسو میزنه؟ :

کد:
private void btnCreateCircle_MouseEnter(object sender, EventArgs e)
        {
            toolTip1.Show("Add Circle To GroupBox Test Control", btnCreateCircle);
         
        }

        private void btnCreateCircle_MouseLeave(object sender, EventArgs e)
        {
            toolTip1.Hide((Button)sender);
        }

        private void btnCreateCircle_MouseMove(object sender, MouseEventArgs e)
        {
            toolTip1.Show("Add Circle To GroupBox Test Control", btnCreateCircle, e.Location);
        }

به نظر میاد مشکل از رویداد btnCreateCircle_MouseMove باشه اما چه مشکلی؟!
ویندوز مسئول نمایش و کنترل Tooltip ئه، اگه بگید این Tooltip رو نشون بده اول Tooltip قبلی رو ناپدید می کنه.شما دارید برای هر تکان کوچیک ماوس مجددا فرمان نمایش Tooltip رو می دهید. طبیعتا پاک کردن قبلی باعث پر پر زدن میشه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
کلاس FixedToolTip رو که من نوشتم، ربطی با Tooltip استاندارد ویندوز نداره.

اگر وارث اون کلاس باشند که کاملا درسته، برای مثال هایی که زدید هم درست هست، ولی برای نتیجه گیری کافی نیست. Bitmap واقعا وارث Image هست، اما صرفا از اینکه دیدید در پارامتری این حالت وجود داره نباید نتیجه بگیرید که وارث شه، مادامی که تعریف کلاس اش رو ندیدید همچین نتیجه ای نمی توانید بگیرید که وارث اش هست یا نه. در تعریف هر کلاسی می توانید قابلیت تبدیل implicit به یک کلاس دیگه رو پیاده سازی کنید، فرضا اشیاء کلاس Class1 رو بدون هیچ مشکلی به Bitmap تبدیل کنید، ولی این بدین معنی نیست که Class1 وارث Bitmap ئه یا باهاش سازگاره. اون implicit operator به کامپایلر نشون میده که چطور یه شی Class1 رو به Bitmap تبدیل کنه، کامپایلر هم طبق اون تعریف هیچ خطا یا اخطاری برای همچین تبدیلی نشون نمیده اما این ظاهر قضیه است، Class1 کلا هیچ تناسبی با ساختار Bitmap نداره.
کد:
    class Class1
    {
        public static implicit operator Bitmap(Class1 a)
        {
            return new Bitmap(16, 16);
        }
    }

            Bitmap b = new Class1();
سلام
ممنون استاد علی :rose:
والا با این ساختاری که نوشتید آشنا نیستم و درکش یه کم برام سخته ولی همون تاییدتون برام کافی هه


شما شیء از هر کلاسی که از IWin32Window ارث بری کرده مثل Control رو بهش تحویل بدهید قبوله.
آها . پس نکته اش این بود ولی وقتی کلاس پدر یعنی IWin32Window رو داشته باشیم و سریع ترین روشی که بفهمیم نوادگانش چی هستن رو از کجا باید متوجه شیم؟
اگه از کلاس فرزند بود خوب Go To Defintion رو میزدیم (قبلا گفته بودین) این قدر که هر بار جلوتر بره و ببینینم ولی برعکسش چی؟


ویندوز مسئول نمایش و کنترل Tooltip ئه، اگه بگید این Tooltip رو نشون بده اول Tooltip قبلی رو ناپدید می کنه.شما دارید برای هر تکان کوچیک ماوس مجددا فرمان نمایش Tooltip رو می دهید. طبیعتا پاک کردن قبلی باعث پر پر زدن میشه.

خوب شما هم توی پروژه ای که دادین ، تقریبا شبیه همین کد رو نوشتین پس اونجا چرا سو سو نمیزد و هر بار نمیبست؟!
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
آقا علی ، توی پروژه ی dll نمیشه از فضای نام System.Windows.Forms برای کار با کلاس های بصری (دکمه و ...) استفاده کرد؟
اگه یه راهی داره ، حالا میشه مثلا برای کار با یه شی مثل مثلا شی TreeView (پروپرتی ها و هر چیز دیگه ی شی) ، بجای اینکه شی ای از اون کلاس (مثلا شی ای از کلاس TreeView) دریافت و با اعضای اون شی کار کنیم ، هندل اونو دریافت کنیم؟ اگه میشه ، یه مثال کوچیک میزنین؟ مثلا یه هندل TreeView رو بگیره و پروپرتی Left اون شی رو 10 پیکسل جلوتر ببره
ممنون
 

the_king

مدیرکل انجمن
سلام
ممنون استاد علی :rose:
والا با این ساختاری که نوشتید آشنا نیستم و درکش یه کم برام سخته ولی همون تاییدتون برام کافی هه



آها . پس نکته اش این بود ولی وقتی کلاس پدر یعنی IWin32Window رو داشته باشیم و سریع ترین روشی که بفهمیم نوادگانش چی هستن رو از کجا باید متوجه شیم؟
اگه از کلاس فرزند بود خوب Go To Defintion رو میزدیم (قبلا گفته بودین) این قدر که هر بار جلوتر بره و ببینینم ولی برعکسش چی؟
منوی View ویژوال استدیو گزینه Object Browser رو انتخاب کنید. اول Browser رو تنظیم کنید، مثلا روی یک نسخه Framework یا روی My Solution پروژه ای که باز کرده اید. اسم رو برای جستجو زیرش بنویسید و با Enter جستجو کنید، وقتی به اون مورد خاص که خواستید رسیدید دو تا زیر شاخه داره، Base Types یعنی خودش وارث چه مواردیه و Derived Types یعنی چه مواردی ازش ارث بری کرده اند، البته نتیجه بستگی به انتخاب تون برای Browser داره.

خوب شما هم توی پروژه ای که دادین ، تقریبا شبیه همین کد رو نوشتین پس اونجا چرا سو سو نمیزد و هر بار نمیبست؟!
عرض کردم خدمت تون، ساختار کلاسی که من نوشتم کاملا مستقل ئه، هیچ شباهتی هم به ساختار Tooltip ویندوز نداره که کدشون شبیه هم باشه، صرفا ظاهر نمایشی اش شبیه Tooltip ئه.

آقا علی ، توی پروژه ی dll نمیشه از فضای نام System.Windows.Forms برای کار با کلاس های بصری (دکمه و ...) استفاده کرد؟
اگه یه راهی داره ، حالا میشه مثلا برای کار با یه شی مثل مثلا شی TreeView (پروپرتی ها و هر چیز دیگه ی شی) ، بجای اینکه شی ای از اون کلاس (مثلا شی ای از کلاس TreeView) دریافت و با اعضای اون شی کار کنیم ، هندل اونو دریافت کنیم؟ اگه میشه ، یه مثال کوچیک میزنین؟ مثلا یه هندل TreeView رو بگیره و پروپرتی Left اون شی رو 10 پیکسل جلوتر ببره
ممنون
برای DLL های خود NET. که هیچ مشکلی نیست، شما می توانید هر کلاسی رو بکار ببرید، اعم از Control و غیر Control.
اون چیزی که شما به عنوان Handle اشاره می کنید Handle پنجره است، و معمولا هم کنترل کردنش به این ترتیبه که Message هایی به اون Handle ارسال میشه که هر کد Message یک عملیات خاصی رو انجام میده. اما پنجره با TreeView فرق می کنه، امکاناتی که پنجره در اختیارتون میذاره در حد کلاس TreeView و Property هاش نیست. عملیات هایی مثل تغییر موقعیت پنجره برای هر جور پنجره ای معتبر اند، مگر اینکه در کد خاص اون کلاس خاص جلوی پاسخگویی بهشون گرفته شده باشه، مثلا شما نمی توانید موقعیت پنجره Desktop رو تغییر بدید. اما Property ئه Left ربطی به فرمان های پنجره نداره. شما به Property ئه Left دسترسی ندارید، با فرمانی مثل SetWindowPos یا SendMessage یا GetWindowPlacement یه عملیاتی رو انجام می دهید که منجر به خوندن مقدار یا تغییر Left بشه وگرنه خود Property ابدا به این طریق بدست نمیاد. با اون Handle شما از پنجره فقط بعضی خصوصیات کلی اش رو کنترل می کنید، نه از طریق ساختار کلاس TreeView
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام
ممنون استاد علی
توی قضیه ی handle ، منظورم برای dll های غیر دات نت (unmanaged) بود
----------
آقا ، مگه کلاس ها reference type نیستن؟ الان توی کد زیر ، پس چرا مقدار نهایی رشته ی testString تغییر نکرد؟ :

کد:
private void btnTestString_Click(object sender, EventArgs e)
        {
            string testString = "g";
            StringMethodClass1(testString);
            MessageBox.Show(testString);
        }




private void StringMethodClass1(string stringArg1)
        {
            stringArg1 = "salam";
        }

میدونم مقدار بازگشتی برای تابع نذاشتم ولی کلاس ها که اشاره گر ان و با تغییر مقدارشون ، تغییر میکنن ، پس string که از کلاس هست (نه استراکچر) ، چرا تغییر نکرد؟ در صورتی که این کار رو با یه آرایه یا مثلا یه شی button و هر کلاس دیگه ای میکردیم ، مقدار آخری رو میگرفت
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
یک سئوال دیگه اینکه مگه reference type ها این طور نیستن که همه ی اشیاء از نوع reference type ، به مقدار خاصی در حافظه ی هیپ اشاره میکنن؟ مثلا 2 تا شی از کلاس reference type رو با هم برابر بگیریم ، هر دو ، به یک مقدار (کلاس) در حافظه ی هیپ اشاره میکنن دیگه؟
پس چرا مثلا توی کد زیر ، وقتی btnTest1 رو برابر btnTest2 میکنیم ، فقط تغییرات روی یک کدوم اعمال میشه؟ در صورتی که اگه هر دو ، به یه مقدار اشاره میکنن ، پس باید با تغییر پروپرتی یک کدوم ، هر دو مقدارشون به همون تغییر کنه :


کد:
btnTest1 = new Button();
            btnTest2 = new Button();
            btnTest1.Location = new Point(6, 600);
            btnTest1.Text = "btnTest1";
            btnTest2.Location = new Point(90, 600);
            btnTest2.Text = "btnTest2";
            contGroupBoxTest1.Controls.Add(btnTest1);
            contGroupBoxTest1.Controls.Add(btnTest2);
            btnTest1 = btnTest2;
            btnTest1.Text = "salam";

btnTest1 و btnTest2 بصورت سراسری تعریف شدن قبلا
منظورم اینه که با تغییر پروپرتی btnTest1.Text و یا پروپرتی btnTest2.Text ، باید هر دو شی ، همزمان پروپرتی شون تغییر کنه اما فقط تغییرات روی یک کدوم اونم دومی اعمال میشه
پس منظور از اینکه در reference type ها ، هر دو به یه مقدار اشاره میکنن چیه؟ اگه این طور بود ، با تغییر مشخصات یکی ، همه ، همزمان باید تغییر میکردن که !
 

the_king

مدیرکل انجمن
سلام
ممنون استاد علی
توی قضیه ی handle ، منظورم برای dll های غیر دات نت (unmanaged) بود
----------
آقا ، مگه کلاس ها reference type نیستن؟ الان توی کد زیر ، پس چرا مقدار نهایی رشته ی testString تغییر نکرد؟ :

کد:
private void btnTestString_Click(object sender, EventArgs e)
        {
            string testString = "g";
            StringMethodClass1(testString);
            MessageBox.Show(testString);
        }




private void StringMethodClass1(string stringArg1)
        {
            stringArg1 = "salam";
        }

میدونم مقدار بازگشتی برای تابع نذاشتم ولی کلاس ها که اشاره گر ان و با تغییر مقدارشون ، تغییر میکنن ، پس string که از کلاس هست (نه استراکچر) ، چرا تغییر نکرد؟ در صورتی که این کار رو با یه آرایه یا مثلا یه شی button و هر کلاس دیگه ای میکردیم ، مقدار آخری رو میگرفت
بله، پارامتر هایی که از نوع کلاس اند با اشاره گر به متد ارسال می شوند اما اینکه به پارامتر مقدار جدیدی نسبت بدهید ربطی به شیء ای که در پارامتر ارسال شده بود نداره.
اگر مثلا اون stringArg1 یک متد یا پروپرتی ای داشت که ازش استفاده می کردید و با اون شیوه محتویاتش تغییر می کرد همان اتفاق مورد نظر شما می افتاد.
یعنی اگر شما تغییری در محتویات اون شیء ای که با پارامتر stringArg1 ارسال شده می دادید حرف تان درست بود، ولی شما با "salam" = یک شیء جدید رو داخل stringArg1 قرار داده اید، توجه داشته باشید که "salam" = یک شیء جدیدی با مقدار "salam" می سازه. شیء قبلی ویرایش نشده، همونطور که بود هست.
خلاصه اینکه در متد StringMethodClass1 شما به پارامتر stringArg1 یک شیء جدید نسبت دادید، نه اینکه تغییری در مقدار شیء داخلش بدهید.

یک سئوال دیگه اینکه مگه reference type ها این طور نیستن که همه ی اشیاء از نوع reference type ، به مقدار خاصی در حافظه ی هیپ اشاره میکنن؟ مثلا 2 تا شی از کلاس reference type رو با هم برابر بگیریم ، هر دو ، به یک مقدار (کلاس) در حافظه ی هیپ اشاره میکنن دیگه؟
پس چرا مثلا توی کد زیر ، وقتی btnTest1 رو برابر btnTest2 میکنیم ، فقط تغییرات روی یک کدوم اعمال میشه؟ در صورتی که اگه هر دو ، به یه مقدار اشاره میکنن ، پس باید با تغییر پروپرتی یک کدوم ، هر دو مقدارشون به همون تغییر کنه :


کد:
btnTest1 = new Button();
            btnTest2 = new Button();
            btnTest1.Location = new Point(6, 600);
            btnTest1.Text = "btnTest1";
            btnTest2.Location = new Point(90, 600);
            btnTest2.Text = "btnTest2";
            contGroupBoxTest1.Controls.Add(btnTest1);
            contGroupBoxTest1.Controls.Add(btnTest2);
            btnTest1 = btnTest2;
            btnTest1.Text = "salam";

btnTest1 و btnTest2 بصورت سراسری تعریف شدن قبلا
منظورم اینه که با تغییر پروپرتی btnTest1.Text و یا پروپرتی btnTest2.Text ، باید هر دو شی ، همزمان پروپرتی شون تغییر کنه اما فقط تغییرات روی یک کدوم اونم دومی اعمال میشه
پس منظور از اینکه در reference type ها ، هر دو به یه مقدار اشاره میکنن چیه؟ اگه این طور بود ، با تغییر مشخصات یکی ، همه ، همزمان باید تغییر میکردن که !
شما دو تا شی دکمه مستقل رو با ()new Button ساخته اید، حالا اینکه تو کدوم متغیر ها مقدارشون رو نگه داشته اید یا اصلا نگه نداشته اید هیچ اهمیتی نداره :
کد:
            btnTest1 = new Button();
            btnTest2 = new Button();
            btnTest1.Location = new Point(6, 600);
            btnTest1.Text = "btnTest1";
            btnTest2.Location = new Point(90, 600);
            btnTest2.Text = "btnTest2";
            contGroupBoxTest1.Controls.Add(btnTest1);
            contGroupBoxTest1.Controls.Add(btnTest2);
بعد در متغیر btnTest1 که قبل از این به شیء دکمه اول اشاره می کرد شیء دکمه دوم رو قرار داده اید، یعنی عملا یک مقدار اشاره گر رو در یک اشاره گر دیگه کپی می کنید :
کد:
            btnTest1 = btnTest2;
این مساله هیچ ربطی به مقدار قبلی متغیر نداره. نه بلایی سر شیء اول میاد و نه اشیاء با هم ترکیب می شوند و نه شیء دوم تغییری می کنه، صرفا یک متغیر که قبلا به یک شیء اشاره می کرد به یک شیء دیگه اشاره می کنه.
btnTest1 و btnTest2 هر دو در حقیقت اشاره گر اند با یک حافظه ناچیز خیلی کوچک، حافظه اشیآء اون تا دکمه که قطعا بزرگتره جای دیگری از حافظه است و جابجایی این دو تا متغیر ربطی به اونها نداره.
کد:
            btnTest1.Text = "salam";
شما با متغیر btnTest1 شیء دکمه دوم را کنترل می کنید، اینکه قبلا اون متغیر به چه شیء ای اشاره می کرد تاثیری در عملکرد این کد نداره.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
بله، پارامتر هایی که از نوع کلاس اند با اشاره گر به متد ارسال می شوند اما اینکه به پارامتر مقدار جدیدی نسبت بدهید ربطی به شیء ای که در پارامتر ارسال شده بود نداره.
اگر مثلا اون stringArg1 یک متد یا پروپرتی ای داشت که ازش استفاده می کردید و با اون شیوه محتویاتش تغییر می کرد همان اتفاق مورد نظر شما می افتاد.
یعنی اگر شما تغییری در محتویات اون شیء ای که با پارامتر stringArg1 ارسال شده می دادید حرف تان درست بود، ولی شما با "salam" = یک شیء جدید رو داخل stringArg1 قرار داده اید، توجه داشته باشید که "salam" = یک شیء جدیدی با مقدار "salam" می سازه. شیء قبلی ویرایش نشده، همونطور که بود هست.
خلاصه اینکه در متد StringMethodClass1 شما به پارامتر stringArg1 یک شیء جدید نسبت دادید، نه اینکه تغییری در مقدار شیء داخلش بدهید.

سلام
ممنون استاد علی:rose:
من دقیق متوجه نشدم
منظورتون اینه که اگه همون مقدار ورودی stringArg1 رو تغییر میدادم و شی جدیدی بهش نسبن نمیدادم ، حرف من درست میشد؟
اگه آره ، پس این کد چرا جواب نمیده؟ :


کد:
        private void btnTestString_Click(object sender, EventArgs e)
        {
            string testString = "g";
            StringMethodClass1(testString);
            MessageBox.Show(testString);
        }

        private void StringMethodClass1(string stringArg1)
        {
            stringArg1 += " ab";
        }
اگه اشتباه نکنم ، این ، چون به مقدار قبلی ، یه مقداری رو اضافه میکنه ، دیگه شی جدید نیست. درسته؟
من الان یه آرایه رو تست کردم . کاملا گیج شدم!
الان این کد درسته . خوب . مشکل خاصی روش نیست :

کد:
private void btnTestString_Click(object sender, EventArgs e)
        {
            string[] testString = { "a",  "b", "c"};
            string[] newStr = { "z", "y", "h" };
            testString = newStr;
            MessageBox.Show(testString[0]);
        }

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

کد:
private void btnTestString_Click(object sender, EventArgs e)
        {
            string[] testString = { "a",  "b", "c"};
            StringMethodClass1(testString);
            MessageBox.Show(testString[0]);
        }


        private void StringMethodClass1(string[] stringArg1)
        {
            string[] newStr = { "z", "y", "h" };
            stringArg1 = newStr;
        }
باید برای تغییرش ، مثل value type ها (یعنی بر عکس حالتی که در کد بالا نوشته شد) ، دونه دونه ی اعضای آرایه رو ریخت توی آرایه ی stringArg1 تا مثل کد اولی عمل کنه :
کد:
        private void btnTestString_Click(object sender, EventArgs e)
        {
            string[] testString = { "a",  "b", "c"};
            StringMethodClass1(testString);
            MessageBox.Show(testString[0]);
        }


        private void StringMethodClass1(string[] stringArg1)
        {
            string[] newStr = { "z", "y", "h" };
            for (int i = 0; i < newStr.Length; i++)
            {
                stringArg1[i] = newStr[i];
            }
        }
چرا این طورن؟

شما دو تا شی دکمه مستقل رو با ()new Button ساخته اید، حالا اینکه تو کدوم متغیر ها مقدارشون رو نگه داشته اید یا اصلا نگه نداشته اید هیچ اهمیتی نداره :
کد:
            btnTest1 = new Button();
            btnTest2 = new Button();
            btnTest1.Location = new Point(6, 600);
            btnTest1.Text = "btnTest1";
            btnTest2.Location = new Point(90, 600);
            btnTest2.Text = "btnTest2";
            contGroupBoxTest1.Controls.Add(btnTest1);
            contGroupBoxTest1.Controls.Add(btnTest2);
بعد در متغیر btnTest1 که قبل از این به شیء دکمه اول اشاره می کرد شیء دکمه دوم رو قرار داده اید، یعنی عملا یک مقدار اشاره گر رو در یک اشاره گر دیگه کپی می کنید :
کد:
            btnTest1 = btnTest2;
این مساله هیچ ربطی به مقدار قبلی متغیر نداره. نه بلایی سر شیء اول میاد و نه اشیاء با هم ترکیب می شوند و نه شیء دوم تغییری می کنه، صرفا یک متغیر که قبلا به یک شیء اشاره می کرد به یک شیء دیگه اشاره می کنه.
btnTest1 و btnTest2 هر دو در حقیقت اشاره گر اند با یک حافظه ناچیز خیلی کوچک، حافظه اشیآء اون تا دکمه که قطعا بزرگتره جای دیگری از حافظه است و جابجایی این دو تا متغیر ربطی به اونها نداره.
کد:
            btnTest1.Text = "salam";
شما با متغیر btnTest1 شیء دکمه دوم را کنترل می کنید، اینکه قبلا اون متغیر به چه شیء ای اشاره می کرد تاثیری در عملکرد این کد نداره.

آها ممنون
یعنی اینکه قبل از عمل انتصاب ، یعنی قبل از کد :


کد:
btnTest1 = btnTest2;

شی btnTest1 ، به شی دکمه اول (شی btnTest1 در حافظه ی هیپ) اشاره میکرد . و بعد از عمل انتصاب ، مقدار اشاره گر این شی تغییر کرد و بنابراین دیگه به شی btnTest2 اشاره میکنه و این طوری هست که دیگه دسترسی به شی btnTest1 به اولین دکمه نداره . btnTest2 هم که از اول به دکمه ی دومی اشاره میکرد پس با تغییر هر کدوم از این اشیاء (بعد از عمل انتصاب) ، فقط دکمه ای که بهش اشاره میشه یعنی دکمه ی دوم ، ویژگی هاش تغییر میکنه
ممنون
یه چیز دیگه اینکه ، بعد از عمل انتساب و با توجه به اینکه مقدار اشاره گر دکمه ی اول ، از دست میره ، garbage collection سی شارپ ، اشیاء مربوط به دکمه ی اول رو اتوماتیک ، از بین میبره برای مدیریت حافظه؟
 

the_king

مدیرکل انجمن
سلام
ممنون استاد علی:rose:
من دقیق متوجه نشدم
منظورتون اینه که اگه همون مقدار ورودی stringArg1 رو تغییر میدادم و شی جدیدی بهش نسبن نمیدادم ، حرف من درست میشد؟
اگه آره ، پس این کد چرا جواب نمیده؟ :


کد:
        private void btnTestString_Click(object sender, EventArgs e)
        {
            string testString = "g";
            StringMethodClass1(testString);
            MessageBox.Show(testString);
        }

        private void StringMethodClass1(string stringArg1)
        {
            stringArg1 += " ab";
        }
اگه اشتباه نکنم ، این ، چون به مقدار قبلی ، یه مقداری رو اضافه میکنه ، دیگه شی جدید نیست. درسته؟
من الان یه آرایه رو تست کردم . کاملا گیج شدم!
الان این کد درسته . خوب . مشکل خاصی روش نیست :

کد:
private void btnTestString_Click(object sender, EventArgs e)
        {
            string[] testString = { "a",  "b", "c"};
            string[] newStr = { "z", "y", "h" };
            testString = newStr;
            MessageBox.Show(testString[0]);
        }

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

کد:
private void btnTestString_Click(object sender, EventArgs e)
        {
            string[] testString = { "a",  "b", "c"};
            StringMethodClass1(testString);
            MessageBox.Show(testString[0]);
        }


        private void StringMethodClass1(string[] stringArg1)
        {
            string[] newStr = { "z", "y", "h" };
            stringArg1 = newStr;
        }
باید برای تغییرش ، مثل value type ها (یعنی بر عکس حالتی که در کد بالا نوشته شد) ، دونه دونه ی اعضای آرایه رو ریخت توی آرایه ی stringArg1 تا مثل کد اولی عمل کنه :
کد:
        private void btnTestString_Click(object sender, EventArgs e)
        {
            string[] testString = { "a",  "b", "c"};
            StringMethodClass1(testString);
            MessageBox.Show(testString[0]);
        }


        private void StringMethodClass1(string[] stringArg1)
        {
            string[] newStr = { "z", "y", "h" };
            for (int i = 0; i < newStr.Length; i++)
            {
                stringArg1[i] = newStr[i];
            }
        }
چرا این طورن؟



آها ممنون
یعنی اینکه قبل از عمل انتصاب ، یعنی قبل از کد :


کد:
btnTest1 = btnTest2;

شی btnTest1 ، به شی دکمه اول (شی btnTest1 در حافظه ی هیپ) اشاره میکرد . و بعد از عمل انتصاب ، مقدار اشاره گر این شی تغییر کرد و بنابراین دیگه به شی btnTest2 اشاره میکنه و این طوری هست که دیگه دسترسی به شی btnTest1 به اولین دکمه نداره . btnTest2 هم که از اول به دکمه ی دومی اشاره میکرد پس با تغییر هر کدوم از این اشیاء (بعد از عمل انتصاب) ، فقط دکمه ای که بهش اشاره میشه یعنی دکمه ی دوم ، ویژگی هاش تغییر میکنه
ممنون
شما چه از =+ استفاده کنید و چه از = به هر حال با توجه به ساختار کلاس string یک شیء جدید رو داخل متغیر قرار می دهید، کلاس string راهی برای ویرایش مقدار داخل شیء ارائه نکرده، هیچ متدی نداره که اینکار رو انجام بده. بر خلاف خیلی از زبانها حتی اجازه تغییر یک حرف از رشته رو هم ندارید، باید کلا شیء جدیدی ساخته بشه :
کد:
            string a = "test";
            a[0] = 'b';         // Error : Property or indexer 'string.this[int]' cannot be assigned to -- it is read only
بنا بر این راهی برای نمایش اون مثالی که میخواهید در مورد string نیست. هر عملی که انجام می دهید یک شیء string جدید ساخته میشه.

یه چیز دیگه اینکه ، بعد از عمل انتساب و با توجه به اینکه مقدار اشاره گر دکمه ی اول ، از دست میره ، garbage collection سی شارپ ، اشیاء مربوط به دکمه ی اول رو اتوماتیک ، از بین میبره برای مدیریت حافظه؟
نه، Garbage collector در آزاد کردن حافظه خیلی محتاط ئه، اشیاء وقتی اجازه دارند که از حافظه آزاد شوند که یا خودتان با متد Dispose درخواست اش رو کرده باشید و یا دیگه هیچ اشاره گری بهش اشاره نکنه، یعنی هیچ جایی آثار استفاده ای برایش نمونده باشه.
مادامی که اون شیء ساخته شده در حافظه جایی استفاده میشه Garbage collector اقدامی برای حذف کردنش نمی کنه، مثلا در کد شما شما شیء دکمه رو در فرم قرار داده اید، پس در مجموعه Controls ای هم بهش اشاره گر وجود داره. پس مادامی که اون شیء فرم از حافظه حذف نشه یا دکمه ها از مجموعه Controls ها در نیاد اشیاء دکمه ها توسط Garbage collector از حافظه آزاد نخواهند شد چون در حال استفاده اند.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
شما چه از =+ استفاده کنید و چه از = به هر حال با توجه به ساختار کلاس string یک شیء جدید رو داخل متغیر قرار می دهید، کلاس string راهی برای ویرایش مقدار داخل شیء ارائه نکرده، هیچ متدی نداره که اینکار رو انجام بده. بر خلاف خیلی از زبانها حتی اجازه تغییر یک حرف از رشته رو هم ندارید، باید کلا شیء جدیدی ساخته بشه :
کد:
            string a = "test";
            a[0] = 'b';         // Error : Property or indexer 'string.this[int]' cannot be assigned to -- it is read only
بنا بر این راهی برای نمایش اون مثالی که میخواهید در مورد string نیست. هر عملی که انجام می دهید یک شیء string جدید ساخته میشه.


نه، Garbage collector در آزاد کردن حافظه خیلی محتاط ئه، اشیاء وقتی اجازه دارند که از حافظه آزاد شوند که یا خودتان با متد Dispose درخواست اش رو کرده باشید و یا دیگه هیچ اشاره گری بهش اشاره نکنه، یعنی هیچ جایی آثار استفاده ای برایش نمونده باشه.
مادامی که اون شیء ساخته شده در حافظه جایی استفاده میشه Garbage collector اقدامی برای حذف کردنش نمی کنه، مثلا در کد شما شما شیء دکمه رو در فرم قرار داده اید، پس در مجموعه Controls ای هم بهش اشاره گر وجود داره. پس مادامی که اون شیء فرم از حافظه حذف نشه یا دکمه ها از مجموعه Controls ها در نیاد اشیاء دکمه ها توسط Garbage collector از حافظه آزاد نخواهند شد چون در حال استفاده اند.

ممنون استاد علی
ولی این تیکه از سئوالم هنوز باقی موند . ممنون میشم جواب بدین :


من الان یه آرایه رو تست کردم . کاملا گیج شدم!
الان این کد درسته . خوب . مشکل خاصی روش نیست :

کد:
private void btnTestString_Click(object sender, EventArgs e)
        {
            string[] testString = { "a",  "b", "c"};
            string[] newStr = { "z", "y", "h" };
            testString = newStr;
            MessageBox.Show(testString[0]);
        }

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

کد:
private void btnTestString_Click(object sender, EventArgs e)
        {
            string[] testString = { "a",  "b", "c"};
            StringMethodClass1(testString);
            MessageBox.Show(testString[0]);
        }


        private void StringMethodClass1(string[] stringArg1)
        {
            string[] newStr = { "z", "y", "h" };
            stringArg1 = newStr;
        }
باید برای تغییرش ، مثل value type ها (یعنی بر عکس حالتی که در کد بالا نوشته شد) ، دونه دونه ی اعضای آرایه رو ریخت توی آرایه ی stringArg1 تا مثل کد اولی عمل کنه :
کد:
        private void btnTestString_Click(object sender, EventArgs e)
        {
            string[] testString = { "a",  "b", "c"};
            StringMethodClass1(testString);
            MessageBox.Show(testString[0]);
        }


        private void StringMethodClass1(string[] stringArg1)
        {
            string[] newStr = { "z", "y", "h" };
            for (int i = 0; i < newStr.Length; i++)
            {
                stringArg1[i] = newStr[i];
            }
        }
چرا این طورن؟

نه، Garbage collector در آزاد کردن حافظه خیلی محتاط ئه، اشیاء وقتی اجازه دارند که از حافظه آزاد شوند که یا خودتان با متد Dispose درخواست اش رو کرده باشید و یا دیگه هیچ اشاره گری بهش اشاره نکنه، یعنی هیچ جایی آثار استفاده ای برایش نمونده باشه.
مادامی که اون شیء ساخته شده در حافظه جایی استفاده میشه Garbage collector اقدامی برای حذف کردنش نمی کنه، مثلا در کد شما شما شیء دکمه رو در فرم قرار داده اید، پس در مجموعه Controls ای هم بهش اشاره گر وجود داره. پس مادامی که اون شیء فرم از حافظه حذف نشه یا دکمه ها از مجموعه Controls ها در نیاد اشیاء دکمه ها توسط Garbage collector از حافظه آزاد نخواهند شد چون در حال استفاده اند.

اگه بعد از عمل انتصاب ، به فرم اضافه کنیم ، توسط Garbage collector حذف میشه اون شی؟ :

کد:
            btnTest1 = new Button();
            btnTest2 = new Button();
            btnTest1.Location = new Point(6, 600);
            btnTest1.Text = "btnTest1";
            btnTest2.Location = new Point(90, 600);
            btnTest2.Text = "btnTest2";

            btnTest1 = btnTest2;
            btnTest1.Text = "salam";
            contGroupBoxTest1.Controls.Add(btnTest1);
 

جدیدترین ارسال ها

بالا