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

شروع موضوع توسط saalek110 ‏27 دسامبر 2006 در انجمن برنامه‌نویسی C و هم خانواده‌هایش

  1. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43
    سلام
    استاد علی ، چیزی که در پست بالا گفتم ، درسته؟
    شی this ، اشاره گری به شی ای که فراخونی اش کرد هست . یعنی در مثال زیر :

    کد (Text):
        class C : B
        {
        }

        class B : A
        {
            public B GetThis()
            {
                return this;
            }
        }

        class A
        {
        }
    کد (Text):
    C c = new C();
                B b = c.GetThis();
                MessageBox.Show(b.GetType().ToString());
    this در کلاس B و در متد GetThis ، اشاره به شی new C() که در متغییری از نوع C (با نام c) ریختیم میکنه اما خوب مشخص هست که در داخل خود کلاس B به اعضای فرزندش یعنی C دسترسی نداریم.
    در واقع کلمه ی کلیدی this در داخل متد GetThis رو میشه شبیه این شی و متغییر فرض کرد :

    کد (Text):
    B b = new C();
    درسته؟؟
     
    نوشته شده توسط SajjadKhati در ‏15 جولای 2017
  2. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,270
    تشکر شده:
    10,203
    امتیاز دستاورد:
    113
    نمیتونم درستی شو تایید کنم چون اون new کار رو خراب می کنه. اون this شبیه به اینه this = (B) instance . حالا ممکنه instance یک شیء از هر نوعی باشه که B هم محسوب میشه. این صرفا یک Cast ئه، فرض رو بر این میگیره که اون this از نوع B ئه. ممکنه حقیقتا یک B باشه یا یک فرزندی از B، نوه B، نتیجه B و ...
    یک مساله دیگه هم هست که مربوط به دسترسی به اعضاء یک شیء ئه. اینکه چیزی موقع تایپ کردن نشون داده نمیشه الزاما به این معنی نیست که بهش دسترسی وجود نداره. فرضا this مورد نظر حقیقتا از نوع C بوده،
    حالا شما در کلاس B به عنوان یک شیء C می توانستید به اعضاء Public اش دسترسی داشته باشید، ولی چون this فیلدی از نوع B فرض شده ادیتور اعضاء C رو نشون نمیده. ولی به این معنی نیست که دسترسی بهشون وجود نداره.
    کد (Text):
            class C : B
            {
                public void CC()
                {
                    MessageBox.Show("C");
                }
            }

            class B : A
            {
            }

            class A
            {
            }

      A x = new C();
      x.GetType().GetMethod("CC").Invoke(x, null);
     
     
    نوشته شده توسط the_king در ‏15 جولای 2017
    SajjadKhati از این پست تشکر کرده است.
  3. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43

    ممنون استاد علی
    اگه فکر میکنید که منظورم از new اینه که شی جدید در نظر دارم ، نه این طور نیست . مثال زدم فقط .
    هر چند اون کد آخری رو درست متوجه نشدم ولی این جوری هم میشه مثال زد دیگه؟ درسته؟ هر دو مثال ، یه مقصود رو میرسونن دیگه؟ :

    کد (Text):
            class C : B
            {
                public object Meth()
                {
                    return "abc";
                }
                public void CC()
                {
                    MessageBox.Show("CC");
                }
                public string RetString()
                {
                    return "salam";
                }
            }

            class B : A
            {
                public B GetThis()
                {
             
                    return this;
                }
                public string AccessToInstanceMember()
                {
                    if (this is C)
                        return ((C)this).RetString();
                    else
                        return null;
                }
            }

            class A
            {
            }

    و


    کد (Text):
                Page2Class.B x = new Page2Class.C();
                x.AccessToInstanceMember();

    --------------------------------------------------------------------

    بعد اینکه ، در ادامه ی داستان قبل که در پنج پست قبلی گفتم (پستی که عکس گذاشتم و قضیه ی کلاس های DefaultUserControl و Page1 و Page2 رو گفتم که کلاس های Page1 و Page2 از کلاس DefaultUserControl به ارث میبرن) ، در کلاس DefaultUserControl ، میخوام آرایه ای تعریف کنم از جنس خود همون کلاس تا اگه شی ای از اون کلاس (کلاس Page1 یا Page2 و ...) قبلا ساخته شده بود و توی این آرایه بود (یعنی اون عضو از آرایه null نبود) ، اون عضو از آرایه رو Show کنه وگرنه چون موقع کلیک روی دکمه های Page ، چون از کلاس Page1 و ... شی ساخته میشه ، شی جاری رو Hide کنه . کدش اینه :

    کد (Text):
    namespace Practice_1
    {
        public partial class DefaultUserControl : UserControl
        {
            public Form mainForm;
            private DefaultUserControl[] Pages { get; set; }
            public int MyTest = 5;
            public DefaultUserControl()
            {
                InitializeComponent();
            }

            public DefaultUserControl(Form syncForm_UsrCtrl)
            {
                InitializeComponent();
                mainForm = syncForm_UsrCtrl;
                this.Size = mainForm.ClientSize;
                this.Pages = new DefaultUserControl[5];
            }

            private void btnPage1_Click(object sender, EventArgs e)
            {
                if (this.Pages[0] == null)
                {
                    this.Pages[0] = this;
                    Page1 page1 = new Page1(mainForm);
                    mainForm.Controls.Add(page1);
                    //this.Dispose();
                   
                    this.Hide();

                    if (this is Page2)
                        MessageBox.Show(this.ToString() + "\n" + ((Page2)this).MyTest);
                }
                else
                    this.Pages[0].Show();
               
            }

            private void btnPage2_Click(object sender, EventArgs e)
            {
                this.Pages[1] = this;
                Page2 page1 = new Page2(mainForm);
                mainForm.Controls.Add(page1);
                //this.Dispose();
                this.Hide();
            }
        }
    }
     

    اما چیزی که تعجبم رو برمیانگیزه و برام سئواله اینه که با اونکه پروپرتی Pages ، سراسری تعریف شد ، ولی با اجرا شدن رویداد btnPage1_Click ، درست میشه (یعنی عضو 0 ام اش مقدار میگیره) اما با اجرا شدن رویداد btnPage2_Click ، دوباره همه ی مقادیرش رو از دست میده وهمه ی اعضای آرایه ، null میشن . چرا؟؟!!
    البته کد رویداد btnPage2_Click کامل نیست که مهم نیست
     
    آخرین ویرایش: ‏15 جولای 2017
    نوشته شده توسط SajjadKhati در ‏15 جولای 2017
  4. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,270
    تشکر شده:
    10,203
    امتیاز دستاورد:
    113
    اعضاء اون نیستن که، اعضاء یک کنترل دیگه هستند.شما تو کد btnPage1_Click نوشتید ;()this.Hide و مخفی اش کردید، دیگه دکمه های اون کنترل دیده نمیشه که بخواهید روی دکمه دومش کلیک کنید. شما در ادامه و موقع فشار دادن دکمه دوم دارید روی دکمه های Page1 page1 = new Page1 ئه کلیک می کنید که یک شیء دیگه است.
     
    نوشته شده توسط the_king در ‏15 جولای 2017
    SajjadKhati از این پست تشکر کرده است.
  5. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43
    ممنون . بله بله ، اصلا حواسم نبود
    چند تا سئوال مختلف دارم استاد علی
    اول اینکه آیا این کار شدنی نیست که مثلا از شی ای که در دست داریم (یا رشته) ، بشه شی ای از یک کلاس ساخت؟ یعنی مثلا ما دکمه ای با نام Page1 داریم (یا حتی مثدار text این دکمه ، "Page1" باشه یا کلا یه شی دیگه) .جدای از این ، کلاس Page1 و Page2 و ... هم داریم . میخوام همه ی آبجکت های دکمه رو به ییه رویداد وصل کنم جوری که روی دکمه ی Page1 که کلیک شد ، شی ای از کلاس Page1 بسازه و روی دکمه ی Page2 که کلیک شد ، شی ای از کلاس Page2 ساخته بشه و ...
    این شدنی هست؟ اگه به این روش شدنی نیست ، کلا روشی وجود داره که با یه الگوریتم ، به جواب کلی رسید و لازم نباشه هر بار شرط گذاشت که مثلا اگه فلان دکمه کلیک شد ، فلان شی رو بسازه و ...؟
    --------------------
    بعد اینکه در هر کلاس هایی مثل یوزر کنترل و فرم ، متد اورراید شده ی Dispose با کد زیر وجود داره :

    کد (Text):
    protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    انگار این شی components همیشه null هه و هیچ وقت غیر از null نمیشه تا دستور components.Dispose(); اجرا بشه !! پس چرا این تیکه رو و کلا این متد رو اورراید کردن؟!
    -------------------
    سوم اینکه میشه با سی شارپ ، برای افترافکت پلاگین نوشت؟ یا به صورت دیگه ، زبان نوشتن پلاگین برای افترافکت ، فقط سی پلاس پلاس هست یا نه؟ و راه ها و توابع و کلاس های لازم برای نوشتن پلاگین برای افترافکت چیه؟ و کلا باید از چه مسیری رفت تا بشه براش پلاگین نوشت؟
     
    نوشته شده توسط SajjadKhati در ‏16 جولای 2017
  6. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,270
    تشکر شده:
    10,203
    امتیاز دستاورد:
    113
    فشار دادن دکمه با شیوه فراخوانی وصله به یک متد داخلی OnClick و البته از این On فلان ها زیاده. میتوانید override اش کنید و هر کدی برای اجرا شدن موقع کلیک بنویسید. در مورد دسترسی به کلاس ها و سازنده ها و ... هم همه موارد مورد نیاز زیر مجموعه namespace ئه System.Reflection هست که بهتون امکان میده در پروژه تون فرضا کلاسی به اسم x رو پیدا کنید. مشخصات داخلش رو بفهمید. به delegate سازنده هاش دسترسی پیدا کنید و فرضا یکی شون رو اجرا کنید تا شیء ای ساخته بشه. کلا مثال های System.Reflection رو تو گوگل جستجو کنید خیلی موارد قابل استفاده اینطوری پیدا میشه. حالا مثالی که شما میزنید شاید خیلی کاربرد عمومی نداشته باشه ولی وقتی میخواهید در یک کلاس نامشخص دنبال موارد خاصی بگردید که از هیچ interface یا class خاصی نیستند ولی با یک ویژگی هایی هماهنگ اند به System.Reflection نیاز پیدا می کنید.

    اشتباه می کنید. یک UserControl جدید و خام بسازید، کامپایل کنید و یک نمونه اش رو روی فرم تون قرار بدید. اون کد ;()components.Dispose رو تو پیاده سازیش پیدا کنید و سطرش رو انتخاب کنید. کنار کدتون یک Breakpoint بذارید (کلید F9) و کد تون رو اجرا کنید و ببینید موقعی که دارید فرم رو می بندید و قراره Dispose بشه چطور اون سطر اجرا میشه و کد در حالت Debug سرش وایمیسته. (با F10 سطر به سطر اجرا ادامه پیدا می کنه)

    من با پلاگین های Adobe After Effects آشنایی ندارم، بحث پلاگین هاش هم مربوط به انجمن خودشه، اما کلا اگه پلاگین هاش فایل های exe یا dll اند، محال ئه زبان نوشتن پلاگین فقط ++C باشه، ++C شامل یکی دو کامپایلر خاص هم که نیست، مهم استاندارد خروجی کامپایلر ئه، اینکه به چه زبانی نوشته شده خیلی مهم نیست. در سفت و سخت ترین شرایط ممکنه از کتابخانه هایی استفاده کنه که از نوع cdecl باشند و کامپایلر بعضی زبان ها که صرفا از stdcall استفاده میکنه نتونه باهاشون کار کنه یا فرضا از یک کتابخانه های lib ای استفاده کنند که کتابخانه های static اند و این شراط محدود کننده است، چون صرفا در بعضی کامپایلر ها امکان link دادن به یک کتابخانه static هست، در #C مستقیما نمی توانید از lib استفاده کنید، باید برایش یک Wrapper در ++C نوشته بشه. شاید برای اینکه در #C بخواهید پلاگین بنویسید به یک Wrapper کنارش نیاز داشته باشید.
    یا به ساده ترین شکل ممکن، صرفا نمونه کد پلاگین در اون زبان موجود باشه و تنبلی شون بیاد به زبان دیگه ای بازنویسی اش کنند. ولی نمیشه محدود به ++C باشه.

    پلاگین هر برنامه ای یکسری تعاریف داره که باید تو کد نویسی اش رعایت بشه، مثلا متد های Export شده فلان و بهمان رو باید حتما داشته باشه که ورودی هاشون پارامتر هایی از نوع فلانه و مقدار خروجی شون از نوع بهمان. و یا فرضا به کتابخانه فلان باید حتما ارجاع داده بشه و متد بهمان فراخوانی بشه. برای هر برنامه ای پلاگین می نویسید یا مستنداتش رو میخونید و طبق اون متد ها رو تو زبان دلخواهتون ایجاد می کنید و یا راحت تر یه نمونه پلاگین خالی رو که کدش به همون زبونه باز می کنید و تغییرش میدید.
     
    نوشته شده توسط the_king در ‏16 جولای 2017
    SajjadKhati از این پست تشکر کرده است.
  7. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43
    ممنون استاد علی
    من که نمیدونم ولی یه کم باهاش کار میکنم ببینم جواب میگیرم یا نه اما الان با کلاس System.Reflection.Emit.AssemblyBuilder کار میکنم ، اما نمیذاره ازش شی بسازم . چرا؟ آخه یه کلاس دیگه هم قبلا بود و نمیذاشت ازش شی درست کنم (یادم نمیاد چی بود دقیقا) در صورتی که هر دو ، چیزی که باعث بشه شی ازش نسازیم ندارن یعنی مثلا الان این کلاس AssemblyBuilder ، نه static هست و نه abstract که نذاره ازش شی درست کنیم . پس دلیل اینکه نمیذاره ازش شی درست کنیم ، چیه؟


    تست کردم اما همون بود . مثل بقیه ی یوزر کنترل ها ، شی components اش null بود!


    ممنون
    پلاگین های استاندارد افترافکت ، پسوند aex دارن البته پسوند exe هم بعضی هاشون دارن
     
    نوشته شده توسط SajjadKhati در ‏16 جولای 2017
  8. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,270
    تشکر شده:
    10,203
    امتیاز دستاورد:
    113

    ساده ترین حالتش اینه که متد سازنده کلاس public نیست، حتی اگه internal هم باشه برای شما که خارج از اسمبلی اش هستید غیر قابل دسترس ئه.

    کد تون در Debug روی اون سطر متوقف شد؟ اگه متوقف نشده باشه که هیچ، یه جایی از کار ایراد داره، وگرنه اگه متوقف شده نمیتونسته null باشه چون اونوقت شرط برقرار نبود که به اجرا کد برسه.
    اگر null باشه یه چیزی در کار تون ایراد داره، چون معنی اش اینه که InitializeComponent اجرا نشده. کدتون دست کاری شده وگرنه شما وقتی یک UserControl جدید می سازید ویژوال استدیو در متد سازنده کلاسش فراخوانیش می کنه. متد سازنده دیگه ای هم نداره که دورش بزنه. در متد InitializeComponent هم که با new شیء جدید ساخته میشه، محاله همینطوری null بشه. یا اشتباه می کنید و null نیست یا کد دستکاری شده ای رو دارید تست می کنید که InitializeComponent تو اجراش نیست.
    کد (Text):
        public partial class UserControl1 : UserControl
        {
            public UserControl1()
            {
                InitializeComponent();
            }
        }

      private void InitializeComponent()
      {
      components = new System.ComponentModel.Container();
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
      }
     
     
    نوشته شده توسط the_king در ‏16 جولای 2017
    SajjadKhati از این پست تشکر کرده است.
  9. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43

    ممنون
    آها پس یه کم هم دستکاری کنیم ، کد :


    کد (Text):
      private void InitializeComponent()
      {
      components = new System.ComponentModel.Container();
      }

    پاک میشه ! چرا؟؟! این شی ، چه ربطی به دستکاری کردن یا نکردن یوزر کنترل ها داره؟!
     
    نوشته شده توسط SajjadKhati در ‏16 جولای 2017
  10. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43
    اون قضیه ی پست قبلی (ایجاد شی Page1 و ... با شی یا متن دیگه) رو آخر بجاش با switch نوشتم و کدش این جوری شد :

    کد (Text):
    private void btnPage1_Click(object sender, EventArgs e)
            {
                Button clickedPage = (Button)sender;
                DefaultUserControl myPage = null;
                int clickedPageNumber;

                if ( !Int32.TryParse(VBString.Right(clickedPage.Text, 1), out clickedPageNumber) )  // اگه مقدار TryParse فلس بود خطا برگردونه و دیگه ادامه ی کدها اجرا نمیشه
                    throw new Exception("خطای تبدیل به عدد");

                clickedPageNumber--;  // یک عدد کم کنه برای یکی شدن در آرایه
                if (DefaultUserControl.Pages[clickedPageNumber] == null)  // اگه عدد و ایندکس شماره ی صفحه در آرایه نبود و اون عضو از آرایه خالی بود ، شی جدید رو توی اون ایندکس از آرایه بریزه و به فرم اضافه کنه
                {
                    switch (clickedPageNumber)
                    {
                        case 0:
                            myPage = new Page1(mainForm);
                            break;
                        case 1:
                            myPage = new Page2(mainForm);
                            break;
                    }
                   
                    mainForm.Controls.Add(myPage);
                    int thisPageNumber;
                    if (Int32.TryParse(VBString.Right(this.Text, 1), out thisPageNumber))
                    {
                        thisPageNumber--;
                        if (DefaultUserControl.Pages[thisPageNumber] == null)
                        {
                            DefaultUserControl.Pages[thisPageNumber] = this;
                        }
                       
                    }
                   
                    DefaultUserControl.Pages[clickedPageNumber] = myPage;
                    this.Hide();
                    myPage.Show();
                }
                else  // وگرنه اون شی در آرایه رو مخفی و نمایش بده _ صفحه ی جاری رو مخفی و صفحه ای که روش کلیک شد رو نمایش بده
                {
                    DefaultUserControl.Pages[clickedPageNumber].Show();
                    this.Hide();
                }
            }

    همه ی رویدادهای دکمه ها رو بهش وصل میکنم . چون این کد فقط مخفی میکنه صفحه رو و صفحه ی مورد نظر رو نمایش میده (شی اش در رم میمونه و dispose نمیکنم) ، سرعت نمایش صفحه اش خیلی بیشتر از قبلی هست ولی رم بیشتری مصرف میکنه
    اما اگه میشد بجای switch از الگوریتم بهتری استفاده کرد ، خوب میشد :green:
     
    نوشته شده توسط SajjadKhati در ‏16 جولای 2017
  11. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,270
    تشکر شده:
    10,203
    امتیاز دستاورد:
    113
    دستکاری منظورم ویرایش کد کلاس ئه، نه تغییر شکل کنترل. به ویرایش کد کلاس ربط داره، با حذف و اضافه کردن کنترل ها پاک نمیشه.
    این کد باید همیشه باشه و اجرا بشه، اگه components ئه null پس پاکش کردید، خودش که خود به خود پاک نمیشه.
     
    نوشته شده توسط the_king در ‏16 جولای 2017
    SajjadKhati از این پست تشکر کرده است.
  12. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43

    ممنون
    ولی فقط در صورتی که من دقیقا همون بصورت پیش فرض بمونه ، اون کد سرجاش هست ولی با تغییر مثلا تغییر رنگ پشت زمینه ی یوزر کنترل ، اون خط کد ، پاک میشه!
     
    نوشته شده توسط SajjadKhati در ‏16 جولای 2017
  13. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,270
    تشکر شده:
    10,203
    امتیاز دستاورد:
    113
    یکجور بهینه سازی ئه، وقتی بهش نیازی نیست حذفش می کنه، متغیرش رو هم حذف می کرد بهتر بود، یه کمپوننت مثل یک Timer یا BackgroundWorker که بهش نیاز داره رو روی کنترل تون اضافه کنید مجددا کد رو میذاره سر جاش.
     
    نوشته شده توسط the_king در ‏17 جولای 2017
    SajjadKhati از این پست تشکر کرده است.
  14. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43
    ممنون
    اما برای چی هست ، قشنگ نفهمیدم این شی components
    ------------------------
    بعد اینکه استاد علی ، چرا کد (قضیه ی عملگر لامبدا) زیر مشکل داره؟ :
    داخل فضای نام :

    کد (Text):
    public delegate int DynamicMethod(int par1, int par2);
    داخل کلاس :
    کد (Text):
    public DynamicMethod dynamicMethodObj;
    داخل یک رویداد از همون کلاس :
    کد (Text):
    int a = 10, b = 20;
                dynamicMethodObj = (a, b) =>
                {
                    MessageBox.Show("Dynamic Method 1");
                    return a * b;
                };

    بجای a و b که مشکل میگیره ، مقدار لیترال عدد هم بدیم ، بازم یه مشکل دیگه میگیره؟ مشکلش چیه و چجوری باید حل بشه؟
    فقط در صورتی که دلیگیت مون ، هیچ آرگومان ورودی ای نگیره ، درست کار میکنه !

    ویرایش :
    آها ببخشید متوجه شدم . چون داریم در اینجا شی تابع براش تعریف میکنیم ، دقیقا همون متغییر با نام هایی که توی پارامترهای دلیگیت نوشتیم رو براش بنویسیم یعنی par1 و par2 رو براش بنویسیم یعنی باید کد رویداد رو به شکل زیر تغییر بدیم :


    کد (Text):
    int a = 10, b = 20;
                dynamicMethodObj = (par1, par2) =>
                {
                    MessageBox.Show("Dynamic Method 1");
                    return a * b;
                };

                dynamicMethodObj(a, b);
    ---------------------------------------------------

    فقط اینکه در کد زیر ، چرا رویداد اولی که اجرا شد ، حالا که میخوایم رویداد دومی رو اجرا کنیم ، حتی توی رویداد دومی ، با اونکه a=2 و b=4 هست ، ولی a و b در رویداد اول که 10 و 20 هست رو برای تابع یا دلیگیت dynamicMethodObj میفرسته (و در نتیجه مقدار 200 رو برمیگردونه) ؟!!!
    به ظاهر باید مقدار a و b در رویداد خودش رو بفرسته که !! :


    کد (Text):
    private void btnDynamicMeth1_Click(object sender, EventArgs e)
            {
                int a = 10, b = 20;
                dynamicMethodObj = (par1, par2) =>
                {
                    MessageBox.Show("Dynamic Method 1");
                    return a * b;
                };

                dynamicMethodObj(a, b);
            }

            private void btnDynamicMeth2_Click(object sender, EventArgs e)
            {
                int a = 2, b = 4;
                int c = dynamicMethodObj(a, b);
                MessageBox.Show(c.ToString());
            }
     
    آخرین ویرایش: ‏17 جولای 2017
    نوشته شده توسط SajjadKhati در ‏17 جولای 2017
  15. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,270
    تشکر شده:
    10,203
    امتیاز دستاورد:
    113
    کمپوننت ها یکجا رو میخوان که بشینن و از اونجا مدیریت بشن. اگه شما فرضا Timer رو که یک کمپوننت ئه و روی فرم قرار نمیگیره رو بیارید در کلاس فرم، کجا بشینه؟ Designer ویژوال استدیو باید یک مجموعه ای باشه که کمپوننت ها رو داخلش ببینه. این مجموعه نباشه کمپوننت مثل یک متغیر میشه که بجایی وصل نیست و ول شده بحال خودش. اون components ئه هست که باید این کمپوننت ها رو داخل قرار بده و مدیریت کنه و با Designer ویژوال استدیو هماهنگ بشه. از لحاظ ساختار خیلی ساده است، ظاهرش یک مجموعه است که عضو بهش اضافه و کم میشه ولی بودنش خیلی مهمه.

    نشد که، دو تا پارامتر ورودی تعریف می کنید ولی بجای اینکه از اونها استفاده کنین از متغیر های بیرون اش استفاده می کنین :
    کد (Text):
                int b = 10, a = 20;
                dynamicMethodObj = (par1, par2) =>
                {
                    MessageBox.Show("Dynamic Method 1");
                    return par1 * par2;
                };
                dynamicMethodObj(a, b);
     
    چون برای نوشتن کد داخل متد تون از پارامتر های ورودیش استفاده نمی کنین.
     
    نوشته شده توسط the_king در ‏17 جولای 2017
    SajjadKhati از این پست تشکر کرده است.
  16. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43
    ممنون
    بله بله . بازم حواسم نبود :green: کد رو که تغییر دادم ، اون بخشش رو فراموش کردم تغییر بدم (قسمت بازگشتی رو) . اما بازم به نظر میرسه نباید ربطی به متغییرهای a و b در کد و رویداد اول میداشت
    ------------------
    استاد علی ، این کد چرا ارور میده :

    کد (Text):
    public ref int RefMethod()
            {
                int myNum = 5;
                return ref myNum;
            }
    و حتما باید توی آرایه متغییرمون رو تعریف کنیم تا جواب بده
    اما کد زیر چرا درسته ؟ :

    کد (Text):
    private void btnRefType4_Click(object sender, EventArgs e)
            {
                int a = 4;
                ref int b = ref a;
                MessageBox.Show(a.ToString());
                b = 10;
                MessageBox.Show(a.ToString());
            }
    اگه بخاطر اینه که کد اول value type هه که ارور میداد ، خوب کد دوم هم value type هه ، پس چرا ارور نمیده و ref متغییر a ریخته شد توی ref متغییر b ؟!!
     
    نوشته شده توسط SajjadKhati در ‏17 جولای 2017
  17. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,270
    تشکر شده:
    10,203
    امتیاز دستاورد:
    113
    نه این ref مستقیما ربطی به value type و reference type بودن نداره، در هر دو حالت میشه ref ایجاد کرد، الزامی نیست که حتما reference type باشه. اما به value type هایی میتونه ارجاع بده که متعلق به چیزی باشند که بشه بهش ارجاع داد. یعنی این ارجاع دادن تمام و کمال و بدون شرط نیست.
    بهتون اجازه نمیده myNum رو با ref برگردونید چون فقط مواردی رو میتونه برگردونه که یا از بیرون اون متد به داخل اومده اند (یعنی خودشون ارجاع دارند) و یا اگه داخل بدنه متد ایجاد شده اند ذاتا ارجاع داشته باشند، یا اگه ارجاع ندارند جزئی از یک شیء یا آرایه هستند (چون کلاس و آرایه که خودش یکجور کلاس ئه ذاتا ارجاع داره)
    متغیر های محلی ای مثل myNum و همچنین اگه پارامتری مثل int x در اون متد داشتید اون پارامتر x قابل برگردوندن نیستند، مثل متغیر محلی ای میمونه که بیرون از بدنه متد نیست و نمیشه بهش ارجاع داد.
    از نظر فنی چیزی رو می تونه با ref برگردونه که بتونه بهش یک reference پایدار بده. داخل خود btnRefType4_Click میتونه برای متغیر a ارجاع ایجاد کنه ولی وقتی از متد در بیاد دیگه راهی برای ارجاع دادن بهش و یا حفظ کردن در حافظه نداره. اینکار رو با آرایه می توانید بکنید، چون آرایه ذاتا یک آدرس حافظه پایدار داره و بخاطر اون ارجاع (حالا نه الزاما همین ref، هر جور ارجاعی به اون آرایه) میتونه در حافظه نگهش داره و reference پایدار ایجاد کنه. اینکار رو با فیلد های struct نمیتونه بکنه چون اونم مثل int myNum یک فیلد از یک ساختار ئه که نمیشه بیرون از بدنه متد بهش ارجاع داد.
     
    نوشته شده توسط the_king در ‏18 جولای 2017
    SajjadKhati از این پست تشکر کرده است.
  18. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43
    ممنون استاد علی :rose:
    من یه چیز بگم ، میترسم عصبانی بشین (چون قبلا درباره اش بحث کردیم):green: ولی من کامل متوجه نشدم . شما هم گفتین دیگه استراکچر و هیپ رم رو هم قضیه شو جدا نکنم و نگم :green: ولی تحلیل مو میگم ، اگه تمایل داشتین جواب بدین (چون توی آموزش فردام نیاز دارم)
    این تحلیل درسته براش؟ :
    وقتی استراکچری تعریف میکنیم که ریفرنس بهش میدیم :

    کد (Text):
    int a = 4;
    ref int b = ref a;
    مقدار متغییر a (یعنی مقدار4) که بازم در استراکچر هست ، اشاره گر به خونه ی حافظه اش (مثلا شماره خونه اش 2000 هست) توی مقدار متغییر b میریزه
    در متغییرهای محلی ، چون بعد از تابع ، متغییر و مقدارش توی رم پاک میشه ، واسه همین آدرسی وجود نخواهد داشت که بهش اشاره کنه واسه همین یک تابع ، اشاره گر به متغییرهای استراکچر محلی رو نمیتونه برگردونه
    درسته؟
     
    نوشته شده توسط SajjadKhati در ‏18 جولای 2017
  19. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,270
    تشکر شده:
    10,203
    امتیاز دستاورد:
    113
    تحلیل تون یه ایرادی داره، آدرس حافظه ئه سر جاشه، یعنی ممکنه متغیر های یه متد دیگه تو همون آدرس بشینه. در ضمن شما اگه یه شیء از کلاس فلان هم در متغیر محلی بذارید اون متغیر صرفا در داخل متد وجود داره، بیرون متد پاک میشه. حتی اگه بهش ارجاع ندید، بیرون متد توسط GC با تاخیر شیء از بین میره. تفاوت در وجود مکانیسمی ئه که بشه ارجاع رو حفظ کرد، نه اینکه متغیر حذف نشه. متغیر محلی همیشه بیرون متد از بین میره.
    مشکل فنی اینه که وقتی بهش ref دادید باید از بین نره و بخاطر اون ref حافظه اش حفظ بشه، نه حافظه متغیر، حافظه مقداری که توشه. تو طراحی زبان متغیر محلی ای مثل int a همچین مکانیسمی نداره که بشه حفظش کرد.
     
    نوشته شده توسط the_king در ‏19 جولای 2017
    SajjadKhati از این پست تشکر کرده است.
  20. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43
    سلام
    ممنون استاد علی
    یه سئوال ساده دارم اما جواب شو نمیدونم:green:
    در یک فایل :

    کد (Text):
    namespace Install
    {
        class Install
        {
            public int MyFunc(int par1)
            {
                return par1 * par1;
            }
        }
    }
     

    در فایل دیگه :

    کد (Text):
    using Install;

    namespace Player
    {
        class Player
        {
            int a;
            void MyPlayer()
            {
                Install.Install myVar = new Install.Install();
                myVar.MyFunc(10);
            }
        }
    }

    چرا در فایل و کد دوم ، با اونکه فضای نام Install رو using کردیم اما میخوایم شی myVar رو درست کنیم ، در اونجا فضای نام Install رو نمیشناسه و باید این فضای نام رو همراهش بنویسیم؟
     
    نوشته شده توسط SajjadKhati در ‏20 جولای 2017

به اشتراک بگذارید