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

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

  1. SajjadKhati

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

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

    کد (Text):

    namespace T
    {
        class New : New22
        {
            public New(int x)
            {
                MessageBox.Show("Child Class", x.ToString());
            }
        }
    }




     
    کلاس پسر من اینه :

    کد (Text):

    namespace T
    {
        class N : New
        {
            public int x = 30;
            New NewObj = new New(x);
           
            public N(int x) :base(x)
            {


            }
        }
    }
     
    پدربزرگ هم داره ولی مهم نیست
    الان من تو کلاس پسر برام زیر متغییر x داخل خطی که شی تعریف کردم یعنی خط :

    کد (Text):

            New NewObj = new New(x);
     
    خط قرمز میکشه (زیر متغییر x) و میگه :

    a field initializer cannot reference the non-static field,method or property 'N.x'
    مشکلش چیه؟


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


    مشکلش انگار public static نبودن متغییر x تعریف شده در کلاس پسر هست
    اما چرا؟؟؟ چرا غیر از public static باشه رو نمیپذیره؟ تا حالا اینجوری نبود!!!
     
    آخرین ویرایش: ‏8 مارس 2016
    نوشته شده توسط SajjadKhati در ‏8 مارس 2016
  2. the_king

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

    ارسال‌ها:
    10,270
    تشکر شده:
    10,204
    امتیاز دستاورد:
    113
    تو زبان های مدرن شیء گرا ذاتا همه چی بر پایه اشیاء ئه، مثلا متغیری از نوع int داریم، وقتی از متغیر می خواهیم که نوع داده اش را تحویل بدهد یک شیء از نوع Type تحویل می دهد.
    یعنی هم خود داده و هم نوع داده هر دو شیء اند. حالا اگر متغیری رو از نوع یک کلاس خاص هم بسازید همچنان نوع آن کلاس یک Type است که خودش شیء است.

    اما نمی دانم چطور از این شیء بودن نتیجه می گیرید که موقع ساختن شیء بهش دسترسی اضافه می کنیم، چنین نیست. شیء موقع ایجاد شدن فقط ایجاد می شود، دسترسی مربوط به متغیر، متد، مشخصه، کلاس و ... است
    و باید قبلا موقع تعریف شدن مشخص شود. مثلا یک متغیر a حالا فرضا با تعریف ;private Class1 a = null یک متغیر private است، شیء ای داخلش نیست، null است، تهی است. وقتی شیء ای هم داخلش قرار دهید private بودنش تغییر نخواهد کرد.
    شیء ای که ایجاد می کنید و داخلش قرار می گیرد نمی تواند این دسترسی به a را مثلا public کند. از هر متد سازنده ای هم که استفاده کنید همچنان private می ماند.
    شما هر زمانی که ()a = new Class1 را اجرا کنید یک شیء جدید ایجاد می کنید و داخل a قرار می دهید. اگر همون مقدار a را به یک متغیر دیگر که فرضا public است کپی کنید،
    دسترسی private همراهش کپی نمی شود، a همچنان private می ماند و شیء در متغیر دیگر که public است بصورت public قابل دسترسی است. یعنی این خیلی عادی است که
    یک شیء واحد (نه فقط مقدار شبیه به هم، دقیقا یک شیء بصورت مشترک) در متغیر های مختلف بنواند با دسترسی های متفاوتی قرار داشته باشد.

    در سطح کلاس خیلی چیز ها تعریف میشه، متد، مشخصه، فیلد (یا همون متغیر های سراسری)، اندیس، عملگر (مثلا ++ )، رخداد، کلاس و interface و struct و delegate و ...
    اینها همه شون داخل بدنه کلاس تعریف می شوند. هر چی که داخل بلوک { و } کلاس قرار می گیره جزئی از کلاس ئه.

    در اجرای کد کلاس دو بخش اصلی وجود داره، یک بخش مربوط به شیء ئه که از لحظه ای که شیء ایجاد شد اجرا میشه و زمانی که شیء نابود شد از بین میره.
    اما یک بخش دیگه ماهیت خود کلاس ئه و ربطی به اشیاء اش نداره، از لحظه ای که کلاس تعریف شد حالت اجرایی داره، مثلا متغیر ها و متد های static کلاس.
    شما چه از اون کلاس شیء بسازید و چه نسازید اون اجزاء static وجود دارند و برای کل اشیاء کلاس هم مشترکا استفاده می شوند، مثل متغیر های عادی کلاس نیستند که هر شیء ای برای خودش
    مقدار های مستقل داخلشون قرار بده. اگر منظورتون از سطح کلاس اون سطح اجرایی کلاس ئه، متد های static یک نمونه از مواردی است که اتفاقا در اون سطح فراخوانی می شوند.
    تعاریف هم دو دسته اند یک دسته شون مربوط به شیء اند، مثلا متغیر سراسری زمانی ایجاد میشه که شیء رو می سازید. یا متغیر محلی متد وقتی ایجاد میشه که متد رو فراخوانی می کنید.
    اما اجزاء static مربوط به ماهیت کلاس اند، ممکنه بخواهید همان زمانی که برنامه اجرا شد و هنوز شیء ای ساخته نشده یک متد static اجرا بشه یا یک متغیر static سراسری مقدار بگیره، اینها زمانی که
    کلاس تعریف میشه آماده اجرا شدن اند.
    منظورم از تو در تو اینه که یک موردی داخل خودش یک مورد دیگه از همون نوع رو داشته باشه، مثلا حلقه for تو در تو یعنی داخل یک حلقه for حلقه for دیگری قرار بگیره.
    چند ریختی تو در تو هم موقعی پیش میاد که حلقه چند ریختی پدر و فرزند بصورت یک زنجیر از حلقه های تو در تو ادامه پیدا کنه.
    نه interface یک قالب برای یک ساختار مشخصه، خصوصیت اصلیش اینه که فقط قالب ئه، همراه خودش پیاده سازی نداره، داخلش بجز prototype چیزی نیست، ربطی به چند ریختی نداره.

    new یک کلمه کلیدی ئه که چند تا کاربرد داره، اما وقتی برای تعاریف متد و مشخصه بکار می بریدش دقیقا مربوط به همون virtual ئه، وقتی متد یا مشخصه ای override شدنی نیست
    اصلا بکار بردن new در تعریف معنی نداره. new رو می نویسید که کامپایلر بفهمد که شما با اطلاع و آگاهی نسبت به وجود یک مورد با همین نام و مشخصات تمایل دارید مورد جدیدی تعریف کنید.
    وقتی چیزی override شدنی نیست برای چه منظوری باید new قرار بگیرد؟ نسخه جدید چیزی رو تعریف نمی کنید که new بخواهد.
    اگر برای موردی new بکار ببرید که override شدنی نباشد کامپایلر ایراد می گیرد که این new تان بی معنی است و لازم نیست نوشته شود :
    کد (Text):

        class Class1
        {
            public [B][COLOR="#FF0000"]new[/COLOR][/B] void Test()
            {
            }
        }
     
    کد (Text):

    The member 'Class1.Test()' does not hide an inherited member. [B][COLOR="#0000FF"]The new keyword is not required[/COLOR][/B].
     
     
    نوشته شده توسط the_king در ‏8 مارس 2016
    SajjadKhati از این پست تشکر کرده است.
  3. SajjadKhati

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

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43
    ممنون آقا علی
    چرا از یه کلاس وقتی میخایم توی جایی شی ایجاد کنیم نام کلاس رو برامون میاره یعنی اگه سطح دسترسی شو ننویسیم، public میگیره ولی اگه کلاس های تو در تو بنویسیم و اگه برای کلاس داخلی سطح دسترسی مشخص نکنیم ، موقع ایجاد شی ، کلاس داخلی رو توی لیست نمیاره یعنی اتوماتیک سطح دسترسی شو private میگیره بصورت پیش فرض؟
     
    نوشته شده توسط SajjadKhati در ‏8 مارس 2016
  4. SajjadKhati

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

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43
    سلام
    آقا برای فراخونی متدهای static ای که فضای نام اش هم نام فضای نام اون کلاس و متدی هست که از اونجا فراخونی میکنیم ، بازم باید نام فضای نام را بنویسیم؟
    یعنی اگه متد meth در کلاس زیر را :

    کد (Text):

    namespace Project_1
    {
        class Parent
        {
            public static void meth()
            {
                string x = "ali";
            }
        }
    }
     
    بخایم در کلاس زید فراخونی کنیم ، حتما باید نام فضای نام را بنویسیم با اونکه فضای نام هر دو کلاس هم نام هست (یعنی نمیشه بصورت مستقیم نام کلاس و نام متد را فراخوند) ؟ اگه آره ، چرا؟ فضای نام ها که هم نام باشن ، همدیگه رو میشناسن که!! :

    کد (Text):

    namespace Project_1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }


            private void button1_Click(object sender, EventArgs e)
            {
                Class ClassObj = new Class();
                Project_1.Parent.meth();
            }
        }
    }
     
    ممنون
     
    نوشته شده توسط SajjadKhati در ‏19 مارس 2016
  5. SajjadKhati

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

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43
    سلام
    آقا نوع داده ای object چیه؟
    تا حالا توضیحاتی که شنیدم و قبل از آشنایی با نوع داده ای var فکر میکردم که نوع داده ای object همون کار var را میکنه
    ولی الان فهمیدم var همون چیز مورد نظرم بود یعنی اتوماتیک نوع متغییر را تشخیص میده و خیلی به درد عملیات ریاضی و جاهایی که انواع مختلف عددهای رند و غیر رند با هم بکار میره میخوره و کار آدمو راحت میکنه . نوع متغییر var هم موقع نوشتن کد مشخص میشه ولی object و dynamic انگار موقع اجرا برنامه مشخص میشن
    پس نوع داده ای object به درد کجا میخوره؟
    انگار نوع dynamic هم داریم. این باز چیه؟ [​IMG] چن تا!!! فرقشون با هم چی ان؟
    --------------------
    بعد اینکه فایل با پسوند mp3 رو نمیشه بدون ابزار windows media player توی #C پلی کرد؟
    ----------------------------------
    یه سئوال دیگه
    چرا وقتی یه کنترل (مثلا button) به پروژه اضافه میکنیم ، ویژال استودیو اتوماتیک با نام همون کنترل ، برامون از کلاس اش یه شی (instance) ایجاد میکنه و ما از اون به بعد فقط کافیه که اعضاشو مثل پروپرتی ها و متدها و متغییرها و ... برای استفاده و فراخونی نام ببریم (که مشخصه با نقطه جدا میشن) ولی برای فراخونی یک فرم جدید باید خودمون یه شی از کلاس اش ایجاد کنیم؟
    چرا این فرق هست؟ همه مگه کنترل نیستن؟
    --------------------------------------------------
    سئوال دیگه اینکه چجوری میشه توی یک رویدادی کدی بنویسیم که وقتی اون رویداد اتفاق میافته ، اتوماتیک یه دکمه از کیبرد رو برامون فشار بده (نه اینکه کاربر خودش فشار بده) مثلا دکمه F1 یا دکمه Delete و ... رو؟
    --------------------------------------------------
    این کلاس keys در رویدادهای کیبرد دقیقا چیه؟ من کد زیر رو وقتی در رویداد KeyDown (فرم) مینویسم ، هر دکمه ای رو میزنم بهم پیام E رو میده. چرا؟ :


    کد (Text):

                string y = Convert.ToString(Keys.E);
                    MessageBox.Show(y);
     
    مگه نباید فقط وقتی دکمه E را میزنم فقط عمل کنه؟
    ------------------------------------------------------
    و اینکه من در کد زیر که توی رویداد KeyDown گذاشتم ، میخوام وقتی کلیدهای ترکیبی Ctrl+E رو زدم ، بهم پیام بده ولی نمیده . علت اشتباهم کجاست؟ :


    کد (Text):
    [/FONT]
    [FONT=Tahoma]        private void Form1_KeyDown(object sender, KeyEventArgs e)
            {
                if (e.Control==true && e.KeyData==Keys.E)
                {
                    MessageBox.Show(e.Control.ToString()+" + "+e.KeyData.ToString()+" pressed");
                }
               
               
            }

    [/FONT]
    [FONT=Tahoma]
     
    آخرین ویرایش: ‏23 مارس 2016
    نوشته شده توسط SajjadKhati در ‏22 مارس 2016
  6. the_king

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

    ارسال‌ها:
    10,270
    تشکر شده:
    10,204
    امتیاز دستاورد:
    113
    در زبان های شی گرا اصل بر کپسوله سازی ئه، یعنی پنهان سازی تا حد امکان، وقتی شما کلاس ای رو داخل کلاس دیگری تعریف می کنید پنهان سازی تا حد private عملی ئه، به همین جهت اونرو پیشفرض قرار میده.
    اما کلاس ای که داخل کلاس دیگری قرار نگرفته در حالت private معنی نداره، چون اصلا قابل دسترسی نیست. برای همین نمی تونه private باشه. البته پیشفرض برای چنین کلاس هایی internal ئه، public نیست.

    شما هر چیزی رو که تعریف می کنید در یک فضای نام ای تعریف میشه، اون مورد در همون فضای نام بدون اشاره به فضای نام قابل دسترسی ئه. مثلا وقتی در ابتدای کد می نویسید namespace WindowsFormsApplication1
    در ادامه هر موردی که در فضای نام WindowsFormsApplication1 تعریف شده بصورت مستقیم قابل دسترسی ئه. حالا چه در همون فایل یا هر فایل دیگری. حالا اگر فضای نام متفاوتی رو بکار می برید یا باید به فضای نام اشاره کنید
    و یا ابتدای کد با using اون فضای نام رو برای کامپایلر مشخص کنید. تنها جایی مجبور به مشخص کردن صریح فضای نام هستید که یک نام مشابه رو در چندین فضای نام دارید و کامپایلر دچار تردید شده.


    کاربرد var رو ظاهرا خوب متوجه شده اید، در اغلب مواقع موقع ساختن یک شیء مقدار دهی اولیه هم انجام میشه.
    کد (Text):
    StringBuilder s = new StringBuilder();
    برای ساده شدن کد و کاهش دردسر های تغییر نوع داده از var کمک می گیرند. var خودش نوع داده نیست، صرفا انتخاب نوع داده مناسب رو به کامپایلر واگذار می کنه.
    کد (Text):
    var s = new StringBuilder();
    البته var همه جا قابل استفاده نیست، اولا فقط برای متغیر های محلی قابل استفاده است و ثانیا کد باید اونقدر واضح باشه که کامپایلر برای تشخیص نوع داده دچار مشکل نشه، مثلا وقتی شما در یک متغیری مقدار null قرار می دهید
    کامپایلر نمی تونه نوع داده رو تشخیص بده و var برای همچین حالتی قابل استفاده نیست :
    کد (Text):
    var s = null;
    خیر، جز امکانات استاندارد زبان نیست، اگر به فایل wav تبدیل اش کنید می توانید با System.Media.SoundPlayer پخش اش کنید اما فایل mp3 رو باید با یک کمپوننت یا کتابخانه اضافی پخش کنید.
    البته مجبور نیستید کنترل ActiveX روی فرم قرار دهید، می توانید مستقیما با winmm.dll کار کنید :
    کد (Text):

            [System.Runtime.InteropServices.DllImport("winmm.dll")]
            private static extern long mciSendString(string strCommand, StringBuilder strReturn, int iReturnLength, IntPtr hwndCallback);

            public void Play(string filename)
            {
                mciSendString(string.Format("open \"{0}\" type mpegvideo alias MediaFile", filename), null, 0, IntPtr.Zero);
                mciSendString("play MediaFile", null, 0, IntPtr.Zero);
            }
     
    مثلا :
    کد (Text):

                Play(@"D:\MP3\music01.mp3");
     
    شما دکمه رو هنگام طراحی فرم به کلاس فرم اضافه می کنید، در نتیجه متغیری که ویژوال استدیو می سازه موقع ایجاد شدن هر شیء جدیدی از فرم مقدار دهی میشه، یک شیء دکمه داخلش قرار می گیره. اون دکمه فرزندی از اون فرم ئه.
    اما وقتی شما فرم جدیدی می سازید این فرم ارتباطی با سایر فرم ها نداره، فرزند فرم دیگری نیست که ویژوال استدیو بخواهد داخل سایر فرم ها برایش متغیر در نظر بگیرد.

    برای کاربرد های ساده از SendKeys.Send استفاده کنید :
    کد (Text):

    SendKeys.Send("{F1}");
     
    Keys مجموعه کلید هایی است که در ویژوال استدیو تعریف شده. شما اصلا کاری با کلیدی که رخداد مشخص می کنه ندارید، صریحا از ویژوال استدیو متن معادل کلید Keys.E رو می خواهید.
    پارامتر ها در e قرار دارند، شما با e.KeyCode یا e.KeyData کار دارید وگرنه Keys یک مجموعه ثابته :
    کد (Text):

            private void Form1_KeyDown(object sender, KeyEventArgs e)
            {
                string y = Convert.ToString(e.KeyCode);
                MessageBox.Show(y);
            }
     
    e.KeyData مجموعه تمامی کلید هایی است که فشرده شده، فقط Keys.E خالی داخلش قرار نداره. به عملگر | که برای ترکیب دو کلید استفاده شده توجه کنید. اون | عملگر OR رباضی و باینری است.
    با عملگر منطقی و شرطی || متفاوت است. فقط زمانی شرط برقرار است که هم E و هم Control فشار داده شده باشند.
    کد (Text):

                if (e.KeyData == (Keys.E | Keys.Control))
                {
                    MessageBox.Show(e.KeyData.ToString() + " pressed");
                }
     
     
    نوشته شده توسط the_king در ‏29 مارس 2016
    SajjadKhati از این پست تشکر کرده است.
  7. SajjadKhati

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

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43
    سلام و ممنون از توضیحات کامل تون آقا علی
    درباره آرایه ها سئوال داشتم
    نمیشه jaged array ها (آرایه در آرایه) رو کاری کرد که در حلقه ای ، اتوماتیک مثل آرایه های چند بُعدی ، تمام مقادیرشو برگردونه؟ مثل آرایه های چند بُعدی که با حلقه foreach تمام مقادیرشون رو اتوماتیک میشه بدست آورد
    مثلا در این نوع ، آرایه ی زیر چجوری میشه این کار رو کرد؟ :


    کد (Text):

                int[][][] NewMyArray = new int[3][][];
                NewMyArray[0] = new int[2][];
                NewMyArray[1] = new int[4][];
                NewMyArray[2] = new int[2][];




                NewMyArray[0][0] = new int[2];
                NewMyArray[1][0] = new int[2];
                NewMyArray[2][0] = new int[1];




                NewMyArray[0][0][0] = 10;
                NewMyArray[0][0][1] = 20;
                NewMyArray[1][0][0] = 30;
                NewMyArray[1][0][1] = 40;
                NewMyArray[2][0][0] = 50;
     


    پس این طور که فهمیدم اولین کلاس اصل بر آشکار سازیش هست و هر چی که داخل کلاس قرار میگیره حالا چه میخواد کلاس دیگه ای داخل این کلاس باشه یا هر چیز دیگه ای که در کلاس قرار گرفتنی هست مثل متد و متغییر و پروپرتی و ... اصل بر پنهان سازی شونه غیر از اینکه ما سطح دسترسی شونو مشخص کنیم
    درسته؟

    پس اگه اشتباه نکنم نکته ی آخر اینجا مهمه که گفتین : تنها جایی مجبور به مشخص کردن صریح فضای نام هستید که یک نام مشابه رو در چندین فضای نام دارید و کامپایلر دچار تردید شده.

    من خوب متوجه نشدم . الان مگه وقتی شی ایجاد میکنیم ، در واقع داریم نوع داده ای مشخص میکنیم مگه؟ پس چرا بجای نام کلاس که نوع داده ای نیست ، تعیین کننده ی نوع داده ای که var هست گذاشتین؟

    من این کد رو متوجه نشدم یعنی کار توابع و مقادیر آرگومان هاش رو متوجه نشدم مخصوصا مسیر یا متدی که در خط اول در کلوشه فراخونی کردین چیه قضیه اش؟ توی تنها کلوشه هم مگه چیزی میزارن؟ فایل winmm.dll هم باید به پروژه add reference کنم اول؟ اگه آره در کجا وجود داره؟ یعنی توی ویندوز هست یا باید دانلود کنم؟

    یه سئوال دیگه اینکه من بیشتر کارم برای حوضه ی مالیتی مدیاست . یه چند تا کلاس که پروپرتی و متدهای زیاد و بسیار کاربردی در این حوضه باشه چی ها هستن تا بررسی شون کنم؟
    البته مالتی مدیا که میگم نه اینکه در حد پلی کردن آهنگ باشه که اینها بخش کوچیک و فقط برای پلیر مالتی مدیا هست . بیشتر منظورم توابع هایی هست در حوضه ی رمزنگاری فایل ها و کار با درایوهای my computer و کار با فایل ها (کپی و حذف و اجرای فایل در administrator و مجوز دسترسی برای فایل ست کردن و...) و کار با فولدر و کار با اینترنت مثل دانلود فایل و ارسال ایمیل و کار با سرویس ها و پروسس های ویندوز و گرفتن اطلاعات سیستم سخت افزار و سیستم عامل (مثل نوع سیستم عامل و ساعت و تاریخ و ...) و کار با فایل های rar و ... و در کل مجموع توابع و پروپرتی ای که بالای 300 تا 1000 تا در این حوضه بشه و در کل از نرم افزار AMS که در این حوضه توابع داره بیشتر و بهتر بشه

    و اینکه مهمترین سئوالم اینه که یک یا چند متد میخوام که اولا بتونه کنترلی ایجاد کنه (یعنی مثلا کاربر روی دکمه ای کلیک کرد ، یک شی ای که من میخوام میخوام مثل شی tree ایجاد شه) و دوما بتونه توی هر رویدادی از کنترل ها کدی اضافه کنه یا کل کدهای قبلی ای که نوشته شده داخل اون رویداد رو حذف و کد جدید را جایگزین کنه . این قضیه چجوری میشه توی #C ؟

    برای یاد آوری خودم ، فرق or باینری (یک علامت) اینه که همه ی شرط ها اجرا میشه ولی دو علامت که or شرطی هست به محظ غلط بودن اولین شرط ، بقیه رو چک نمیکنه
    ولی چرا حالا اینجا or شرطی اصلا کامپایلر موقع نوشتن کد نمیزاره بنویسیم؟ خوب درسته که or شرطی جواب نمیده ولی این جواب ندادن باید موقع اجرای کد باشه نه اینکه موقع نوشتن کد نزاره بنویسیم
    و سئوال دیگه اینکه پس من چرا با علامت اند (&&) در کد زیر جواب گرفتم ولی در کدی که شما دادین با اند جواب نمیده؟ یعنی کد زیر دقیق کار کد شما رو میکنه :

    کد (Text):

    if(e.Control && e.KeyCode == Keys.E)
                {
                    MessageBox.Show("control+E pressed");
                }
                if (e.KeyCode == Keys.A)
                {
                    MessageBox.Show(e.KeyCode.ToString()+" Pressed");
                }
     
     
    نوشته شده توسط SajjadKhati در ‏5 آوریل 2016
  8. SajjadKhati

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

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43
    یک سئوال دیگه اینکه در زبان لوا (زبان اسکریپت نویسی ای که توی نرم افزار Autoplay Media Studio استفاده میشه) یه قابلیت مهم ای که داره ، نوشتن پترن ها (pattern) در بعضی از توابعی که با رشته ها سرو کار دارن هست و خیلی خیلی کاربردی هست برای کار و انعطاف در رشته ها :

    Pattern ها در لوا

    http://www.lua.org/pil/20.2.html

    http://www.lua.org/pil/20.3.html

    هر چند من مبتدی هستم و شاید توی #C متوجه نشم ولی توی #C قضیه ی پترن ها چجوری هست؟ و توی کدوم متدها استفاده میشه؟ و ... ؟
     
    نوشته شده توسط SajjadKhati در ‏6 آوریل 2016
  9. the_king

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

    ارسال‌ها:
    10,270
    تشکر شده:
    10,204
    امتیاز دستاورد:
    113
    چرا، شدنش که میشه، باید برای اون آرایه تون یک کلاس مجزا بسازید و برای کلاس تون یک کلاس IEnumerator هم بسازید که عضو هاش رو به ترتیب ارائه کنه و بعد برای کلاس اصلی تون IEnumerable رو پیاده سازی کنید و از کلاس IEnumerator ای که ساخته اید شی بسازید و تحویل بدهید.
    توی این تاپیک نمیشه بهش پرداخته بشه، مطلب زیاد داره. در صورت تمایل برایش یک تاپیک مجزا ایجاد کنید.

    اصلی به نام آشکار سازی نداریم، هدف فقط پنهان سازی ئه، اما پنهان سازی از خود برنامه نویس معنی نداره. وقتی به حدی از پنهان سازی برسیم که خود برنامه نویس هم نتونه از کلاسش استفاده کنه، نتیجه می گیریم
    که سطح درستی انتخاب نشده، پس یک درجه پنهان سازی رو کم می کنیم. یا مثلا شما می خواهید برای من یک کتابخانه توابع بسازید، اگر توابع رو private بسازید من نمی توانم ازش استفاده کنم، پس آنها را public می کنید،
    این به معنای این نیست که وقتی برای کسی کتابخانه توابع می نویسید اصل بر آشکار سازی باشه. چون ناچار هستید سطح پنهان سازی رو تقلیل می دهید.

    بله.

    دارید دو تا کار رو با هم انجام می دهید، شما شیء ای تعریف می کنید که متغیرش قبلا معرفی نشده و بهش مقدار مشخصی هم می دهید. var از روی نوع مقدار می تونه تشخیص بده که متغیر از چه نوعی ئه،
    فرضا وقتی مقدار "Sample" را داخل متغیر s قرار می دهید، var می تونه تشخیص بده که نوع داده string برای متغیر شما مناسبه. دیگه لزومی نداره که صریحا مشخص کنید که s یک متغیر از نوع string است.

    کلا صفات رو در بین [ و ] قرار می دهند و صفات از قبل تعریف شده هم خیلی زیاد اند و شما هم می توانید صفت جدید بسازید و ساختارش رو هم شما خودتون تعیین می کنید. بنابر این هر عبارتی که بین [ و ] قرار گرفته ممکنه براتون ناشناخته باشه.
    این DllImport هم یک صفت از پیش تعریف شده ویژوال استدیو است که جزئی از فضای نام System.Runtime.InteropServices ئه.
    سطر پایینی اش برای تعریف کردن یک تابع ئه که در winmm.dll پیاده سازی شده، دقت کنید که تعریف تابع یک عبارت کلیدی extern داره. extern یعنی این تابع رو شما پیاده سازی نمی کنید و کامپایلر داخل برنامه شما دنبال پیاده سازی اش نگرده، به فایل winmm.dll رجوع می کنه.
    کتابخانه ای که با extern توابع اش رو تعریف می کنید نیازی به reference نداره و کاری هم با reference ای که می سازید ندارند. حتی معمولا اینجور کتابخانه ها اصلا اطلاعاتی که بشه بهشون reference داد ندارند.
    winmm.dll جزئی از ویندوز تون ئه، احتمالا بخشی از فایل های Windows Media Player است که بصورت پیشفرض در ویندوز های اروپایی ویرایش N نیست.

    شما کلا باید NET Framework. رو در MSDN بصورت کامل بررسی کنید. یک مواردی مثل کار با فایل های rar ربطی به خود سیستم عامل ندارند و باید از کتابخانه ها و ابزار های دیگر استفاده کنید.

    #C یک زبان مفسری نیست که بتوانید هر جا که خواستید در حین اجرای برنامه بصورت پویا کد جدید بنویسید و اجرا کنید. بنابر این باید از قبل برای هر شرایطی کد نوشته باشید و تا در حین اجرا در صورت لزوم فراخوانی شان کنید.
    اگر ویژوال استدیو نصب باشد با کمک یکسری روتین های خاص Net Framework. می توانید در حین اجرای برنامه پروژه جدیدی بسازید و کامپایل و اجرا کنید ولی برای این منظور قابل استفاده نیست که کد های یک رویداد رو از نو بنویسید.

    ساختن متغیر و تخصیص شی جدید و مشخص کردن موقعیت و ابعاد و قرار دادن فرم فعلی به عنوان Parent اش :
    کد (Text):

    [COLOR="#A9A9A9"]        private void button1_Click(object sender, EventArgs e)
            {[/COLOR]
                var t = new TextBox();
                t.Bounds = new Rectangle(10, 10, 100, 23);
                t.Parent = this;
    [COLOR="#A9A9A9"]        }[/COLOR]
     
    شما می توانید قبل یا در حین اجرای برنامه یک روتین رو به یک رخداد مشخص بچسبانید تا با وقوع رخداد اجرا شود یا جدا کنید تا اجرا نشود ولی نمی توانید کد آن روتین را در حین اجرای برنامه عوض کنید.
    آن روتین موقع کامپایل شدن پروژه تعریف شده و دیگه کدش عوض نمیشه. اما می توانید در حین اجرای برنامه روتین یا روتین هایی که یک رخداد اجرا می کنه رو تعویض کنید.
    کد (Text):

                button1.Click += new EventHandler([B][COLOR="#0000FF"]MyClick[/COLOR][/B]);
     
    کد (Text):

                button1.Click -= new EventHandler([B][COLOR="#0000FF"]MyClick[/COLOR][/B]);
     
    کد (Text):

            void [B][COLOR="#0000FF"]MyClick[/COLOR][/B](object sender, EventArgs e)
            {
                BackColor = Color.Red;            
            }
     
    و می توانید برای شیء جدید دکمه ای که روی فرم قرار می دهید هم رخداد Click را به یک روتین متصل کنید :
    کد (Text):

                var b = new Button();
                b.Parent = this;
                b.Click += new EventHandler(MyClick);
     
    دقت کنید که در #C یک or منطقی با or باینری فرق داره. شما دارید or منطقی رو تعریف می کنید که البته تعریف تون درسته، ولی or باینری کاری با شرط نداره، محاسبه بیتی و باینری می کنه.
    درسته که علامت or باینری و منطقی هر دو شون | ئه و از نظر پیاده سازی داخلی هر دو شون بر پایه محاسبات بیتی اند، ولی در زبان #C این دو عملگر تفکیک شده اند.
    وقتی عملگر | در مورد ارقام صحیح بکار میشه Or باینری و وقتی در مورد bool ها بکار برده میشه Or منطقی ئه. || عملگر Or منطقی شرطی ئه. هم منطقی ئه و هم شرطی.

    کامپایلر || رو فقط برای انواع داده ای که عملگر || رو تعریف کرده اند می تونه بفهمه، برای enum ها عملگر || تعریف نشده. مفهوم منطقی هم نداره. مقداری مثل Keys.E از نظر منطق زبان شرط نیست که برقرار باشه یا نباشه.

    دلیلش تفاوت بین KeyCode و KeyData است. KeyCode صرفا مقدار یک کلید رو که بخاطر اون رخداد فراخوانی شده رو میده، ولی KeyData شامل تمامی کلید های فشرده شده است.
     
    نوشته شده توسط the_king در ‏6 آوریل 2016
    SajjadKhati از این پست تشکر کرده است.
  10. the_king

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

    ارسال‌ها:
    10,270
    تشکر شده:
    10,204
    امتیاز دستاورد:
    113
    یک قضای نام System.Text.RegularExpressions هست که توش Regex و Match و Capture و Group و ... داره.
     
    نوشته شده توسط the_king در ‏6 آوریل 2016
    SajjadKhati از این پست تشکر کرده است.
  11. SajjadKhati

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

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

    سلام
    ممنون از توضیحات کامل تون
    ولی من این تیکه کد رو متوجه نشدم . البته کد قسمت اول رو یه کمی متوجه شدم بجز خط 2 شو . یعنی اینو متوجه شدم :

    کد (Text):

            private void button1_Click(object sender, EventArgs e)
            {
                var t = new TextBox();
                t.Bounds = new Rectangle(10, 10, 100, 23);
                t.Parent = this;
            }
     
    بجز خط 2 شو که نه میدونم پروپرتی Bounds چیه و مخصوصا اینکه توی خط دوم چرا new بکار برده شد؟ مگه new برای اختصاص دادن حافظه برای متغییر و آرایه و شی (که نوعی متغییر میشه) در رم استفاده نمیشه؟ پس چرا در اینجا برای متد استفاده شد؟ و اینکه متد Rectangle که مقداری رو برنمیگردونه که توی پروپرتی t.Bounds ریختین؟؟! و ...!
    کدهای قسمت های دیگه رو متوجه نشدم . البته جدا جدا متوجه میشم ولی اینجا گیج شدم مخصوصا درباره کد :

    کد (Text):

    button1.Click += new EventHandler(button2_Click);
     
    و متد EventHandler و ... کلا هم نمیدونم چیه و هم گیج شدم!
    منظورتون از روتین ، همون کد هست؟

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

    یعنی نمیشه توی ویژال استودیوی به این بزرگی ، شی ای رو که جدید ایجاد کردیم در زمان اجرا (که کد ایجادشو نوشتین) رو توی رویدادش کد دلخواه خودمون رو ست کنیم؟!! نرم افزار Autoplay Media Studio که قابل قیاس با ویژال استودیو نیست این قابلیت رو داره! از طرفی هم این یکی از قابلیت های بسیار مهمه . من دلم به همین ویژال استودیو خوش بود . بدون این قابلیت ، نرم افزار قدرتمندی نمیشه ساخت!!




    برام یه مثال میزنین؟ مثلا رشته ی "Salam0123" اعدادش با این روش پترن ها از رشته اش جدا بشن؟
    درباره پترن ها در #C آموزش فارسی وجود داره؟
     
    آخرین ویرایش: ‏6 آوریل 2016
    نوشته شده توسط SajjadKhati در ‏6 آوریل 2016
  12. the_king

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

    ارسال‌ها:
    10,270
    تشکر شده:
    10,204
    امتیاز دستاورد:
    113
    تو سطر دوم یک متد سازنده ساختار یا struct داریم، یعنی متد سازنده ساختار Rectangle که از شما چهار تا پارامتر عددی دریافت می کند و با new بهش دسترسی پیدا می کنیم.
    کد (Rectangle(10, 10, 100, 23 یک مستطیل در موقعیت x و y ئه 10 و 10 و به طول 100 و عرض 23 ایجاد می کند و بر می گرداند.
    Bounds یکی از مشخصه های اصلی کنترل های ویندوز ئه، ترکیبی است از موقعیت و ابعاد. موقعیت مستقیما در مشخصه Location و ابعاد مستقیما در مشخصه Size قابل دسترسی ئه، و اگر بخواهید هر دو رو همزمان تعیین کنید
    از Bounds استفاده میشه. موقعیت یعنی محل گوشه بالا-سمت چپ کادر که یک Point ئه و ابعاد یعنی طول و عرض که یک Size ئه. با این اطلاعات میشه موقعیت و ابعاد یک کادر مستطیل رو روی صفحه ویندوز و فرم و هر نوع کنترل ای که فرزند دارد تعیین کرد.
    و Rectangle هم که ترکیبی از Point و Size ئه متد نیست، یک ساختار ئه، struct ئه. می توانید از Rectangle شی بسازید و تغییر دهید. مشخصه Bounds از نوع Rectangle است.


    بله، منظورم از روتین هر جور کدی است که در درون یک متد یا مشخصه می نویسید.
    EventHandler یک نوع delegate ئه، شما هم می توانید delegate بسازید. delegate پروتوتایپ یک متد رو تعریف می کنه و کاری به پیاده سازی داخلش نداره. شما یک رخدادی مثل Click دارید که متد هاش پروتوتایپ مخصوص خودشون رو دارند.
    یعنی متد رخداد یکسری پارامتر های مخصوص خودش رو داره و طبیعتا فقط می تونه به متد هایی متصل بشه که دقیقا مشابه همون پروتوتایپ باشند. در مثال مذکور این پروتوتایپ در یک delegate به نام EventHandler تعریف شده. اگر دقت کنید رخداد هایی
    که در فرم و کنترل های روی فرم وجود دارند یک sender و یک پارامتر e دارند. این دو پارامتر به همون EventHandler تعلق دارند :
    کد (Text):

    public delegate void EventHandler(object sender, EventArgs e);
     
    این کد بالا EventHandler رو تعریف می کنه و کل تعریف کردن یک delegate مشابه همین یک سطر ئه، هر متدی که همین پارامتر ها رو داشته باشه با EventHandler سازگار ئه و می تونه به رخداد هایی که همین delegate رو دارند وصل بشه.
    وقتی می خواهید یک متدی رو به یک رخداد متصل کنید، فقط نام متد مثل button2_Click کافی نیست، باید از delegate ای که مربوط به اون رخداد ئه شیء بسازید و اسم متد رو به اون شیء بدهید.
    البته این توضیح کلی ئه و مناسب موارد مرسوم ئه، شما ممکنه یک delegate مخصوص خودتون رو بسازید که جور دیگه ای عمل کنه.
    شما یک زبان ساده مفسری در Autoplay Media Studio دارید که می تونه هر رشته ای رو به عنوان کد زبان دریافت کنه و تفسیر کنه.
    در #C هم یا باید خودتان یک زبان مفسری ساده طراحی کنید و یا از یک کتابخانه یا کمپوننت ای استفاده کنید که یک زبان مفسری به نرم افزار اضافه کنه.
    مثلا زبان Python جزو مواردی است که برای ماکروسازی در نرم افزار ها بکار میره. IronPython که خودش به زبان #C نوشته شده به سایر برنامه های NET. این امکان رو میده که در حین اجرا
    به زبان Python کد بنویسند و اجرا کنند.
    حالا اینکه چرا زبان های پیشرفته ای مثل #C مفسری نیستند یک بحث ئه، و اینکه چون مفسری نیستند پس نرم افزار قدرتمندی نمیشه ساخت یک بحث دیگر.
    لابد به نظر شما به همون دلیل با ++C هم نمیشه نرم افزار قدرتمندی ساخت.

    شاید، دنبال Pattern یا پترن نگردید، عبارت Regex رو جستجو کنید.

    یک الگوی ثابت و مشخص برای هر مساله ای وجود نداره، هر کسی با سبک و شیوه خاص خودش الگو می نویسه.
    کد (Text):

                Regex r = new Regex(@"^(?<word>\D*)(?<number>\d*)$");
                Match m = r.Match("Salam0123");
                string word = m.Groups["word"].Value;
                string number = m.Groups["number"].Value;
     
     
    نوشته شده توسط the_king در ‏6 آوریل 2016
    SajjadKhati از این پست تشکر کرده است.
  13. SajjadKhati

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

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43
    آها به استراکچر و delegate ها برمیگرده؟! من هنوز به این جاها نرسیدم . میگم چرا متوجه نمیشم قشنگ :) باشه بعدا که بهش رسیدم این کد رو بیشتر واکاوی میکنم
    اما مگه متد سازنده توی کلاس و استراکچر یه جور نیستن؟ آخه متد سازنده توی کلاس که مقداری رو برنمیگردونه


    آها یعنی بخاطر اینه که لوا یه زبان مفسری هه و مفسری ها ساده ترن؟ و #C نمیتونه این کار رو کنه چون مثلا نوع داده ای مختلفی دارن و کلا پیچیده ترن...؟
    یعنی اگه بخوایم توی #C این کار رو کنیم باید از زبان مفسری استفاده کنیم؟ اتفاقا خوبی لوا اینه که میتونه تو هر زبان دیگه ای استفاده بشه (فکر کنم توی #C بشه استفاده کرد)
    ولی مشکل اینه که به فرض استفاده از یه زبان مفسری مثل لوا توی #C ، خوب وقتی #C نتونه کدهای خودشو تحلیل کنه ، اون زبان مفسری میتونه برای #C تحلیل کنه؟ و بعد اینکه به فرض اون زبان مفسری بتونه برای #C تحلیل کنه ، حالا منی که تقریبا هیچ چی از #C نمیدونم و مبتدی هستم ، چجوری میتونم همچین متد پیشرفته ای رو درست کنم؟
    من قاتی کردم
    :)


    آها یعنی پترن ها که منظور منه ، توی #C بجاش مبحثی هه بنام Regex
    ممنون
     
    آخرین ویرایش: ‏6 آوریل 2016
    نوشته شده توسط SajjadKhati در ‏6 آوریل 2016
  14. the_king

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

    ارسال‌ها:
    10,270
    تشکر شده:
    10,204
    امتیاز دستاورد:
    113
    چرا بر نمی گردونه؟ پس چطوری در یک متغیر یک شیء رو قرار می دهید؟ اگر متد سازنده کلاس شیء رو بر نمی گردوند که نمی توانستید داخل متغیر قرارش دهید.
    فرضا این یک متد سازنده کلاس :
    کد (Text):

        public class Class1
        {
            public Class1(int x)
            {
            }
        }
     
    یک متغیر هم از نوع این کلاس دارید :
    کد (Text):

    Class1 c;
     
    با کد زیر متد سازنده کلاس رو فراخوانی می کنید و شیء ای می سازید ولی شیء رو در جایی ثبت نمی کنید و بعدا دیگه به اون شیء دسترسی ندارید :
    کد (Text):

    new Class1(12);
     
    ولی اگر در متغیر ذخیره اش کنید بعدا با c به شیء دسترسی دارید :
    کد (Text):

                Class1 c;
                c = new Class1(12);
     
    و متد سازنده یک شیء رو برگردونده که در متغیر c ثبت شده، اگر بر نمی گردوند که نمی توانست در c قرار بگیره.

    احتمالا مشکل تون اینه که نمی دانید می خواهید با امکانات زبان چیکار کنید، وگرنه هر زبانی به اندازه مهارت برنامه نویس اش کارایی داره، حالا چه مفسری باشه و چه کامپایلری.
    کلا از زبان های ساده مفسری برای ماکرو نویسی در نرم افزار های بزرگ استفاده میشه تا کاربرانش بتوانند قابلیت های نرم افزار رو بیشتر کنند، پلاگین بنویسند، چند کار رو در یک مرحله انجام بدهند و ...،
    مثلا AutoLisp برای AutoCad و Python برای FontLab Studio
     
    نوشته شده توسط the_king در ‏7 آوریل 2016
    SajjadKhati از این پست تشکر کرده است.
  15. SajjadKhati

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

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


    ولی من نفهمیدم چجوری با یه زبان مفسری اون کاری که میخوام رو میتونم انجام بدم؟ یعنی چجوری میشه متدی طراحی کرد که توی رویدادها ، کد ست کنه از این طریق
    البته اگه موضوع پیشرفته میشه بعدا که مسلط شدم به زبان کار میکنم و لازم نیست جواب بدین چون به احتمال خیلی زیاد متوجه نمیشم
    :)
     
    نوشته شده توسط SajjadKhati در ‏7 آوریل 2016
  16. the_king

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

    ارسال‌ها:
    10,270
    تشکر شده:
    10,204
    امتیاز دستاورد:
    113
    شیء کلا یک object ئه، فکر کنم قبلا به object اشاره کرده بودم.
    در مثال ها ابتدایی شاید همیشه تعریف متغیر با مقدار دهیش همزمان باشه، اما در عمل موارد زیادی پیش میاد که متغیر یکجا تعریف میشه و مقدار دهی اش در جای دیگری، مثلا در مورد مشخصه ها (Properties)
    این فقط ویژگی #C نیست که برای متد سازنده کلاس مقدار بازگشتی رو صریحا بر نمی گردونند. در زبان ای مثل ++C هم در متد سازنده کلاس نمیشه مقداری رو با return برگردوند، البته return در ++C برای خروج
    از متد هم کاربرد داره، یعنی return الزاما همراه مقدار نیست، می تونه فقط return خالی باشه.
    متد سازنده کلاس یک متد خاص ئه، توضیح خاصی ندارم که دلیل قانع کننده ای برای این باشه که چرا return نداره، قواعد زبان طوری ئه که return نداره، حتی می توانید (public Class1(int x رو اینطوری تفسیر کنید
    که یک متد public است از نوع Class1 که اسم نداره. یعنی Class1 نوع مقدار بازگشتی اش است، نه نام متد، ولی به هر حال return نداره.
    برای رویداد کد ست کردن از دید من اینه، کدی به اسم button2_Click داریم که بعدا به رویداد Click متصل می کنیم. :
    کد (Text):

    button1.Click += new EventHandler(button2_Click);
     
    شما ظاهرا برای کد ست کردن تعریف دیگه ای دارید که کد جدیدی برای button2_Click بنویسید و بعد به رویداد متصل کنید.
    من اصلا نمی دونم شما چه کاری می خواهید انجام بدید، صرفا اشاره کردید که در حین اجرای برنامه کد بنویسید و اجرا بشه که گفتم جزو ویژگی زبان های مفسری ئه.
    حالا این چه کاری است که باید برایش کد در حین اجرای برنامه نوشته بشه اطلاعی ندارم، ولی به هر حال هر کاری به روش های مختلفی قابل انجام ئه.
     
    نوشته شده توسط the_king در ‏7 آوریل 2016
    SajjadKhati از این پست تشکر کرده است.
  17. SajjadKhati

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

    ارسال‌ها:
    691
    تشکر شده:
    193
    امتیاز دستاورد:
    43
    ممنون آقا علی
    آره آبجکت ها رو توضیح دادین . قضیه دوم هم بعدا جلوتر رفتم چک میکنم . الان دقیق متوجه نمیشم
    آقا تو رویداد کیبرد ، این کد چرا جواب نمیده؟ :

    کد (Text):

    if (e.KeyCode == Keys.Control && e.KeyCode == Keys.E)
                {
                    MessageBox.Show("Ctrl + E Pressed");
                }
     
    ولی این کد جواب میده؟ :

    کد (Text):

    if (e.Modifiers == Keys.Control && e.KeyCode == Keys.E)
                {
                    MessageBox.Show("Ctrl + E Pressed");
                }
     
    چرا بجای e.KeyCode == Keys.Control حتما باید e.Modifiers بنویسیم تا جوا بده؟
    قبلا هم که جمله ی زیر رو گفتین قشنگ متوجه نشدم . نمیدونم شاید چون خوب عملگر منطقی و باینری رو نمیشناسم :

    یک منبع خوب نیست که فرق این دو رو مفصل بگه؟
     
    نوشته شده توسط SajjadKhati در ‏8 آوریل 2016
  18. the_king

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

    ارسال‌ها:
    10,270
    تشکر شده:
    10,204
    امتیاز دستاورد:
    113
    شما یک مقدار رو با دو مقدار متمایز مقایسه کردید و بین شان And شرطی قرار داده اید، حداکثر یکی از این دو شرط برقرار می شود، نه هر دو.
    e.KeyCode یک مقداری است، Keys.Control هم مقداری متمایز از Keys.E است. پس محال است که حالتی وجود داشته باشد که e.KeyCode همزمان هم برابر Keys.Control باشد و هم برابر Keys.E
    قبلا هم عرض کردم، e.KeyCode یک کلید فشرده شده است که باعث فراخوانی رخداد شده، یک کلید.
    در ضمن Keys.Control یک modifier ئه، اگر می خواهید کلید Control رو به تنهایی در KeyCode بررسی کنید از Keys.ControlKey استفاده نمایید. فراموش نکنید که e.KeyCode اطلاعات دو کلید
    را نگه نمی دارد.

    این دو تا شبیه هم نیستند که منبعی مفصل به تفاوت شون بپردازه. عملگر های باینری روی اعداد صحیح بدون اعشار محاسبات بیتی انجام می دهند و نتیجه محاسبات همیشه یک عدد صحیح بدون اعشار است.
    مثلا عدد 72 که معادل باینری اش 01001000 است رو با 184 که معادل 10111000 باینری است Or می کنند و نتیجه 248 است که معادل 11111000 باینری است.
    کد (Text):

    int x = 72 | 184;
     
    یا فرضا Not ئه 72 را محاسبه می کنند که 73- می شود :
    کد (Text):

                int x = ~72;
     
    عملگر های منطقی روی مقادیر بولی که یا true هستند و یا false محاسبات منطقی انجام می دهند و نتیجه محاسبات شان هم همیشه یا true است یا false.
    کد (Text):

                bool y = true | false;
     
    کد (Text):

                bool a = (10 > 7);
                bool b = (4 > 20);
                bool y = a | b;
     
    کد (Text):

                bool a = false;
                bool b = !a;
     
    در آموزش های مبانی کامپیوتر و برنامه نویسی مقدماتی ++C و Assembly و ... به عملگر های دودویی / باینری / بیتی پرداخته میشه.
     
    نوشته شده توسط the_king در ‏8 آوریل 2016
    SajjadKhati از این پست تشکر کرده است.
  19. SajjadKhati

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

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



    ممنون آقا علی
    الان کل نکته ی مهم این بود آیا؟ :
    فراموش نکنید که e.KeyCode اطلاعات دو کلید را نگه نمی دارد .

    واسه همینه که هم وقتی از دو تا متغییر رویدادی (البته توی لوا بهشون میگیم متغییر رویدادی اینجا نمیدونم به این e.KeyCode چی میگن :)) استفاده کردم ، چون در آنِ واحد نمیتونه هم مقدار ctrl و هم مقدار E را ذخیره کنه ، پس اجرا نمیکنه؟ و واسه همینه که شما توی کد زیر که قبلا دادین ، از e.KeyData ، دو بار استفاده نکردین؟ :

    کد (Text):

    if (e.KeyData == (Keys.E | Keys.Control))
                {
                    MessageBox.Show(e.KeyData.ToString() + " pressed");
                }
     

    پس همه ی متغییرهای رویدادی این جوری ان که نمیشه همزمان 2 مقدار را ذخیره کنن و اگه بخوایم 2 مقدار متفاوت ازشون رو در شرط بکار ببریم ، یا باید 2 نوع متغییر رویدادی استفاده کنیم (مثل e.Modifiers و e.KeyCode که استفاده کردم) و یا باید مثل شما ، شرط را در یک مقداردهی بگونجونیم (که مشخص هه در این صورت باید مقادیر شرط در داخل پرانتز تعیین بشه) ؟؟
    درباره عملگرها هم ممنون
    به نظرتون بجای استفاده از دو علامت اند یا دو علامت or ، بهتره همیشه از تک علامته شون استفاده کنم؟ یعنی تو شرط ها بجای اینکه بنویسم && فقط بنویسم &
    آخه دو علامته ها گاهی مثل همینجا نمیشن ولی تک علامته ها تا حالا ندیدم مشکل داشته باشن (فرق شونو علی الظاهر انگار میدونم)
     
    نوشته شده توسط SajjadKhati در ‏8 آوریل 2016
  20. the_king

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

    ارسال‌ها:
    10,270
    تشکر شده:
    10,204
    امتیاز دستاورد:
    113
    معمولا هر کاری رو با روش های مختلفی میشه انجام داد که بخشی از سلیقه ای ئه و بخشی اش تجربی. اگر از یکسری نکات زیر رو در نظر نگیرید کدی می نویسید که ظاهرا کار می کند اما بی نقص نیست.
    مثلا من می دانم که اگر شرط (if (e.KeyCode == Keys.E && e.Control را بنویسم برای Ctrl + E برقرار است، ولی نمی نویسم چون اختصاصا برای Ctrl + E نیست، چون چک نمی کند که Shift و Alt در چه وضعیتی هستند.
    برای Ctrl + Alt + E و Ctrl + Shift + E و Ctrl + Shift + Alt + E و کلا هر ترکیبی که در آن E و Control فشرده شده برقرار است. اما وقتی می نویسم ((if (e.KeyData == (Keys.E | Keys.Control دیگر
    هر ترکیب دیگری بجز Ctrl + E شرط را false می کند.
    آن if را با یک شرط می نویسم چون از KeyData یک مقدار بیشتر انتظار ندارم، اصلا نمی دانم اگر بخواهم با دو شرط بنویسم برای شرط دوم چه چیزی را چک کنم، هر چه لازم دارم همان KeyData است،
    KeyData که در یک لحظه چند مقدار ندارد. یک مقدار دارد، آن مقدار یک کلید یا ترکیب or چند کلید است.
    مثلا یک کلید کدش 4 است و کلیدی دیگری کدش 8 است، اینها با هم or شده اند و مقدار 12 را تشکیل داده اند. مقدار 12 یک مقدار بیشتر نیست، ولی ترکیبی از 4 و 8 است که کد دو کلید است.
    شما وقتی مقدار را با 12 مقایسه کنید فشار دادن هر دو کلید رو در یک مرحله بررسی می کنید. شرط دومی لازم نیست، شما فقط برای 12 بررسی اش می کنید.


    به شرط ها توجه کنید، مثلا می گویید اگر کلید E و Control فشار داده شده بودند فلان کار رو انجام بده، این به این معنا است که حالا اگر همراه آنها Alt و Shift را هم فشار دادی قبول است.
    بدیهی است که چک کردن یک شرط از چک کردن دو شرط سریعتر است، پس معمولا || از | و && از & بهتر است چون ممکن است با بررسی شرط اول دیگر نیازی به بررسی شرط دوم نباشد و کد سریعتر اجرا شود.
    گاهی اوقات هم به اجبار باید از && استفاده کنید مثلا :
    کد (Text):

    if (f != null & f.BackColor == Color.Red)
     
    شرط اول این است که f تهی نباشد، اگر تهی باشد و شرط دوم اجرا شود برنامه با خطا متوقف می شود چون وقتی f تهی است نمی توانیم به مشخصه BackColor اش دسترسی داشته باشیم.
    در اینجور موارد حتما باید با && نوشته شود تا اگر تهی بود دیگر شرط دوم بررسی نشود :
    کد (Text):

    if (f != null && f.BackColor == Color.Red)
     
    کلا مورد خاصی باید باشد که بخواهید بجای || از | و بجای && از & استفاده کنید. یعنی جاهایی که لازم است حتما دو شرط به دلیلی اجرا شوند، حتی اگر بررسی یکی شان کفایت می کرد.
    اصولا شرطی که اجرایش سریعتر یا مقدم بر شرط دیگر است را اول می نویسند تا سرعت نسبی اجرای or و and های شرطی بیشتر باشد.
     
    نوشته شده توسط the_king در ‏9 آوریل 2016
    SajjadKhati از این پست تشکر کرده است.

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