PDA

مشاهده نسخه کامل : حلقه و آرایه در سی شارپ



Speed Racer
22-12-18, 13:59
سلام به سجاد عزیزم


چرا کد زیر درسته



Array myArray = new int[] { 12, 13, 14 };


foreach (int item in (int[])myArray)
{
MessageBox.Show(item.ToString());
}



اما کد زیر اشتباهه



Array[] myArray = new int[] { 12, 13, 14 };


foreach (int item in (int[])myArray)
{
MessageBox.Show(item.ToString());
}



در صورتی که هم Array و هم []Array تابع GetEnumerator دارن.

این جمله را تکمیل کن

تابع GetEnumerator در دستور foreach ..........


چون نمی دونم کاربردش چیه نمی تونم تکمیلش کنم

SajjadKhati
22-12-18, 15:46
سلام به سجاد عزیزم


چرا کد زیر درسته



Array myArray = new int[] { 12, 13, 14 };


foreach (int item in (int[])myArray)
{
MessageBox.Show(item.ToString());
}



اما کد زیر اشتباهه



Array[] myArray = new int[] { 12, 13, 14 };


foreach (int item in (int[])myArray)
{
MessageBox.Show(item.ToString());
}



در صورتی که هم Array و هم []Array تابع GetEnumerator دارن.

این جمله را تکمیل کن

تابع GetEnumerator در دستور foreach ..........


چون نمی دونم کاربردش چیه نمی تونم تکمیلش کنم



سلام بر آقا آرشان
اینکه کد دوم اشتباست ، ربطی به اعضای یه کلاس (مثلا در اینجا ربطی به تابع GetEnumerator در این کلاس که گفتید) نداره . وظیفه ی GetEnumerator صرفا اینه که در حلقه ها ، عضو بعدی را مشخص کنه تا حلقه هر بار بتوه عضو بعدی را ببینه . این که کد دوم اشتباست ، به قواعد سی شارپ برمیگرده که رعایت نکردید.
کد دوم اشتباست چون وقتی نوع یه داده را Array مشخص کردید ، میدونید که باید مقدارش را آرایه بدید اما وقتی که نوع یه داده ای را Array[] (آرایه ای از Array ها) مشخص کردید (مثل کد دوم) ، دیگه مقدارش نمیتونه آرایه ی خشک و خالی باشه چون خود Array ، یه آرایه هست و وقتی یه آرایه ی دیگه هم کنارش میذارید ، باید مقدار را آرایه در آرایه بدید (یه آرایه برای Array و یه آرایه برای اون آرایه ای که کنار Array مشخص کردید) . در واقع در کد دوم ، باید مقدار آرایه در آرایه یا همون آرایه های دندانه ای (jagged array) بدید . بنابراین کد دوم را باید به این شکل تغییر بدید :



Array[] myArray = new int[][] { new int[] { 12, 13 }, new int[] { 100, 200 } };


که بنابراین حلقه ی اش این جوری تغییر شکل پیدا میکنه :



Array[] myArray = new int[][] { new int[] { 12, 13 }, new int[] { 100, 200 } };




foreach (int[] firstLevel in myArray)
{
foreach (int secLevel in firstLevel)
{
MessageBox.Show(secLevel.ToString());
}


}



لازم هم نیست در حلقه ، myArray را به چیزی تبدیل کنید .
مبحث آرایه در آرایه (jagged array) ، در قسمت 20 گفته شد .

Speed Racer
22-12-18, 16:04
سلام بر آقا آرشان
اینکه کد دوم اشتباست ، ربطی به اعضای یه کلاس (مثلا در اینجا ربطی به تابع GetEnumerator در این کلاس که گفتید) نداره . وظیفه ی GetEnumerator صرفا اینه که در حلقه ها ، عضو بعدی را مشخص کنه تا حلقه هر بار بتوه عضو بعدی را ببینه . این که کد دوم اشتباست ، به قواعد سی شارپ برمیگرده که رعایت نکردید.
کد دوم اشتباست چون وقتی نوع یه داده را Array مشخص کردید ، میدونید که باید مقدارش را آرایه بدید اما وقتی که نوع یه داده ای را Array[] (آرایه ای از Array ها) مشخص کردید (مثل کد دوم) ، دیگه مقدارش نمیتونه آرایه ی خشک و خالی باشه چون خود Array ، یه آرایه هست و وقتی یه آرایه ی دیگه هم کنارش میذارید ، باید مقدار را آرایه در آرایه بدید (یه آرایه برای Array و یه آرایه برای اون آرایه ای که کنار Array مشخص کردید) . در واقع در کد دوم ، باید مقدار آرایه در آرایه یا همون آرایه های دندانه ای (jagged array) بدید . بنابراین کد دوم را باید به این شکل تغییر بدید :



می شه این دو تا کد رو هم درست کنی


تو کد زیر همه رو object هم میذارم باز هم خطا می گیره



object myArray = new object[] { 12, 15, 25, "salam",'A'


};


foreach (object item in myArray)
{
MessageBox.Show(item.ToString());
}




کد زیر هم درست کن با []Array



Array[] myArray = new double[] { 12, 15, 25.241 };


foreach (double item in (double[])myArray)
{
MessageBox.Show(item.ToString());
}




کلا نیازی هست که ما کد ها رو اینجوری بنویسیم. مثلا آرایه ای که از نوع Int هست ما اونو از نوع Array بنویسم و بعد توی foreach تبدیل کنیم. اصلا این روش کد نویسی استاندارد و درسته

مثلا به این صورت



Array myArray = new int[] { 12, 15, 18 };


foreach (int item in (int[])myArray)
{
MessageBox.Show(item.ToString());
}


مثلا این شکلی باشه که استاندارده که دیگه ما درگیر چند روش کد نویسی نشیم



int[] myArray = new int[] { 12, 15, 18 };


foreach (int item in myArray)
{
MessageBox.Show(item.ToString());
}

SajjadKhati
22-12-18, 23:20
می شه این دو تا کد رو هم درست کنی


تو کد زیر همه رو object هم میذارم باز هم خطا می گیره



object myArray = new object[] { 12, 15, 25, "salam",'A'


};


foreach (object item in myArray)
{
MessageBox.Show(item.ToString());
}




سلامی مجدد
اولین کد :



object myArray = new object[] { 12, 15, 25, "salam", 'A' };


foreach (object item in (object[])myArray)
{
MessageBox.Show(item.ToString());
}


نوع داده ای (یعنی سمت چپ مساوی) متغییری که میخواد توی هر حلقه ای قرار بگیره ، باید توی کلاس یا استراکچرِ (و هر چیز دیگه ای که هست) اون نوع داده ، تابعی بنام GetEnumerator تعریف شده باشه . اون حلقه (foreach ، for و ...) ، از این متد متوجه میشه که در تکرار (یا loop) بعدی ، چه مقداری یا چه عضوی از اون چیز (در اینجا آرایه) را میخونه.
در این کدتون ، چون نوع داده ای myArray تون از نوع object هست و این نوع داده ای هم این تابع را نداره پس نمیتونه توی حلقه شرکت کنه . ولی وقتی myArray را در حلقه ، به نوع مقدارش ( آرایه ای از آبجکت ها یا object[] ) تبدیل میکنید ، چون آرایه ای از هر چیز ، از کلاس Array ارث بری میکنه (یعنی آرایه ای از آبجکت ها هم از کلاس Array ارث بری میکنه) و کلاس Array هم این تابع را داره ، پس مشکلی دیگه نیست





کد زیر هم درست کن با []Array



Array[] myArray = new double[] { 12, 15, 25.241 };


foreach (double item in (double[])myArray)
{
MessageBox.Show(item.ToString());
}




همونطور که در پست قبل گفتم ، وقتی نوع داده ای myArray را از نوع Array[] (آرایه ای از array) میگیرید ، پس باید در مقدارش (سمت راست مساوی) ، یه آرایه برای Array بودن اش بدین (چون همه ی آرایه ها از array ارث بری میکنن و نمیشه متغییری از نوع array باشه اما آرایه نباشه) و یه آرایه ی دیگه برای علامت آرایه ( ای که کنار نوع Array یعنی علامت [] ) که گذاشتید ، بدید. (قضیه ی آرایه در آرایه یا jagged array که در پست بالا مثال اش را گفتم)
اما وقتی مقدار متغییر myArray را آرایه ی یک بعدی میدید ، دیگه نباید نوع داده ای را از نوع Array[] بگیرید (دلیل اش را بالا گفتم) . صرفا کافیه از نوع Array بگیرید :



Array myArray = new double[] { 12, 15, 25.241 };




foreach (double item in (double[])myArray)
{
MessageBox.Show(item.ToString());
}





البته همونطور که گفتم ، لازم هم نیست در حلقه ها ، هر بار متغییرتون (در اینجا myArray) را تبدیل کنید ( در اینجا double[] ) . این تبدیل ، اغلب اوقات نیاز نیست ولی میتونین هم انجام بدین .





کلا نیازی هست که ما کد ها رو اینجوری بنویسیم. مثلا آرایه ای که از نوع Int هست ما اونو از نوع Array بنویسم و بعد توی foreach تبدیل کنیم. اصلا این روش کد نویسی استاندارد و درسته

مثلا به این صورت



Array myArray = new int[] { 12, 15, 18 };


foreach (int item in (int[])myArray)
{
MessageBox.Show(item.ToString());
}


مثلا این شکلی باشه که استاندارده که دیگه ما درگیر چند روش کد نویسی نشیم



int[] myArray = new int[] { 12, 15, 18 };


foreach (int item in myArray)
{
MessageBox.Show(item.ToString());
}




نیاز که بستگی داره . اما کلا کاربرد داره و همچین کدنویسی ای انجام میشه (منظورم نوع داده ای پدر یا اجداد و شی از نوع فرزند یا نوادگان هست) . اگه درکش یه کم سخت هه ، بخاطر اینه که باید مباحث شی گرایی را هم بدونی (قسمت 26 به بعد) . بنابراین اگه اینجا سخت متوجه میشی ، زیاد نگران نباش و خیلی روشون تمرکز نکن .

Speed Racer
23-12-18, 14:36
سلامی مجدد


خیلی ممنونم آقا سجاد از توضیحات کامل شما


سوالی درباره sql server

الان من اگه بخوام sql server از روی کتاب یاد بگیرم می تونم از همون visual studio 2017 استفاده کنم یا باید حتما sql server 2017 یا SQL Server Management Studio رو نصب کنم.بین این دو تا هم گیر کردم که کدوم برای کار من مناسبه.

خود visual studio 2017 Professional تمام دستورات و موارد مورد نیاز sql server که توی کتاب توضیح داده می شه رو توی خودش داره.

SajjadKhati
23-12-18, 15:42
خیلی ممنونم آقا سجاد از توضیحات کامل شما


سوالی درباره sql server

الان من اگه بخوام sql server از روی کتاب یاد بگیرم می تونم از همون visual studio 2017 استفاده کنم یا باید حتما sql server 2017 یا SQL Server Management Studio رو نصب کنم.بین این دو تا هم گیر کردم که کدوم برای کار من مناسبه.

خود visual studio 2017 Professional تمام دستورات و موارد مورد نیاز sql server که توی کتاب توضیح داده می شه رو توی خودش داره.

سلامی مجدد
خواهش میکنم.
من زیاد اس کیو ال کار نکردم ولی در حد همون قدر ، اس کیو ال سرور خود ویژال استودیو برام کافی بود .

Speed Racer
24-12-18, 12:01
سلامی مجدد
خواهش میکنم.
من زیاد اس کیو ال کار نکردم ولی در حد همون قدر ، اس کیو ال سرور خود ویژال استودیو برام کافی بود .

در کد زیر


object myArray = new object[] { };


می تونیم بگیم که این آرایه از نوع object است یا اگه نمی تونیم بگیم دقیقا این جمله به چه صورت می شه.

این آرایه از ..... object است

SajjadKhati
24-12-18, 13:18
در کد زیر


object myArray = new object[] { };


می تونیم بگیم که این آرایه از نوع object است یا اگه نمی تونیم بگیم دقیقا این جمله به چه صورت می شه.

این آرایه از ..... object است

همیشه ، نوعِ یه متغییر را از سمت چپ مساوی تشخیص بده . یعنی مثلا در کد :



Array myArray = new double[] { 12, 15, 25.241 };


متغییر myArray ، از نوع Array هست . چون سمت چپ مساوی ، نوع Array هست .
این را هم بدون که اعضایی که در اینتل لایسنس (صفحه ی راهنما موقع کد نوشتن) لیست میشه ، فقط نوع داده ای (در کد بالا ، نوع Array) را میشناسه . یعنی به مقدار و شی ای که در سمت راست مساوی مینویسیم کاری نداره و اعضای اونو نمیشناسه (مگر اینکه بعدا خودمون تبدیل کنیم)
سمت راست مساوی ، مقدار یا شی داده میشه (که میتونه برابر با خود نوع داده ای ای که در سمت چپ مساوی گذاشتیم باشه یا میتونه از نوع فرزند یا نوادگان نوع داده ای سمت چپ باشه) .
این مباحث ، به شی گرایی ربط داره که در اونحا مفصل توضیح داده شد .
بنابراین در کدی که دادی :



object myArray = new object[] { };


نوع داده ای object هست اما شی (سمت راست مساوی) ، از نوع آرایه ای از object هاست (نه اینکه شی ای از object ها باشه ها) .

Speed Racer
24-12-18, 13:38
همیشه ، نوعِ یه متغییر را از سمت چپ مساوی تشخیص بده . یعنی مثلا در کد :
.

فکر کنم کم کم داری عصبانی می شی انقدر سوال می پرسم.

تو این جمله گفتی


تابعی بنام GetEnumerator تعریف شده باشه . اون حلقه (foreach ، for و ...) ، از این متد متوجه میشه که در تکرار (یا loop) بعدی ، چه مقداری یا چه عضوی از اون چیز (در اینجا آرایه) را میخونه.

می دونیم که آرایه فقط با دستور foreach عمل می کنه که عضوهاش رو بخونه. پس چرا شما از حلقه for و ... نام بردی مگه می شه با حلقه for و while عضوهای یک آرایه رو خوند.
چون اگه for برای نوع int و double و ... باشه که اینا تابع GetEnumerator ندارن و اصلا نیازی هم به این تابع ندارن چون خونده میشن ومشکلی از این بابت ندارن.

SajjadKhati
24-12-18, 14:41
فکر کنم کم کم داری عصبانی می شی انقدر سوال می پرسم.

تو این جمله گفتی



می دونیم که آرایه فقط با دستور foreach عمل می کنه که عضوهاش رو بخونه. پس چرا شما از حلقه for و ... نام بردی مگه می شه با حلقه for و while عضوهای یک آرایه رو خوند.


نمیدانم از کجای حرفم میگی عصبانی میشم! :1. (27):
بله میشه . فقط با دستور و حلقه ی foreach نیست :



Button[] btnArray = new Button[3];
btnArray[0] = new Button();
btnArray[0].Text = "button 1";


btnArray[1] = new Button { Text = "button 2" };
btnArray[2] = new Button { Text = "button 3" };




for (int i = 0; i < btnArray.Length; i++)
{
MessageBox.Show(btnArray[i].Text, "into For loop");
}


int counter = 0;
while (counter < btnArray.Length)
{
MessageBox.Show(btnArray[counter].Text, "into While loop");
counter++;
}




چون اگه for برای نوع int و double و ... باشه که اینا تابع GetEnumerator ندارن و اصلا نیازی هم به این تابع ندارن چون خونده میشن ومشکلی از این بابت ندارن.


دقیقا متوجه نشدم منظورت چیه؟
حلقه ها (for و while و foreach و ...) ربطی به نوع آرایه ندارن . همه شون از تابع GetEnumerator ای که در اون آرایه یا کالکشن (بعدا میخونی) وجود دارن ، عضو بعدی را متوجه میشن که کدوم مقدار را باید خوند . اگه یه نوعی که این تابع را نداشته باشه را توی هر کدوم از حلقه ها بذاری ، چون با اونه که صرفا مقدار بعدی را تشخیص میدن ، اون آرایه ، اون نوع را نمیپذیره و ارور میده (مثل نوع object) .
این را هم دقت کن که متغییری از نوع int یا نوع double را نیست که توی حلقه ها میذاری . بلکه متغییری از نوع آرایه ای از این نوع هاست (int[] و ...) که توی حلقه ها میذاری . هر آرایه ای (حالا از هر نوع میخواد باشه . چه آرایه ای از int ها یا آرایه ای از object ها یا هر آرایه ای از هر نوع دیگه) از کلاس Array ارث بری میکنه و این کلاس Array هست که متد GetEnumerator را داره .

Speed Racer
24-12-18, 15:05
بله میشه . فقط با دستور و حلقه ی foreach نیست :


این آرایه رو با دستور for و while بنویس که عضوهاش رو نشون بده تا متوجه بشم. اگه نمی شه که نمی خواد (اون قبلی که نوشتی برای من پیچیده است)



int[] myArray = new int[] { 10, 12, 14 };

SajjadKhati
24-12-18, 15:19
این آرایه رو با دستور for و while بنویس که عضوهاش رو نشون بده تا متوجه بشم. اگه نمی شه که نمی خواد (اون قبلی که نوشتی برای من پیچیده است)



int[] myArray = new int[] { 10, 12, 14 };

بفرما :



int[] myArray = new int[] { 10, 12, 14 };


for (int i = 0; i < myArray.Length; i++)
{
MessageBox.Show(myArray[i].ToString(), "into For loop");
}


int counter = 0;
while (counter < myArray.Length)
{
MessageBox.Show(myArray[counter].ToString(), "into While loop");
counter++;
}

Speed Racer
24-12-18, 17:14
البته همونطور که گفتم ، لازم هم نیست در حلقه ها ، هر بار متغییرتون (در اینجا myArray) را تبدیل کنید ( در اینجا double[] ) . این تبدیل ، اغلب اوقات نیاز نیست ولی میتونین هم انجام بدین .




کل مطالب رو گرفتم چی شد فقط برای آخرین سوال این قسمت



Array myArray = new double[] { 12, 15, 25.241 };


foreach (double item in (double[])myArray)
{
MessageBox.Show(item.ToString());
}


در کد بالا و در خط دوم کدوم استاندارد تره (طبق MSDN)

با double[] یا بدون اون



foreach (double item in (double[])myArray)




foreach (double item in myArray)





مثلا اگه آرایه ما 10000 عضو داشته باشه در سرعت تاثیر داره این تبدیل اضافه

SajjadKhati
24-12-18, 18:46
کل مطالب رو گرفتم چی شد فقط برای آخرین سوال این قسمت



Array myArray = new double[] { 12, 15, 25.241 };


foreach (double item in (double[])myArray)
{
MessageBox.Show(item.ToString());
}


در کد بالا و در خط دوم کدوم استاندارد تره (طبق MSDN)

با double[] یا بدون اون



foreach (double item in (double[])myArray)




foreach (double item in myArray)





مثلا اگه آرایه ما 10000 عضو داشته باشه در سرعت تاثیر داره این تبدیل اضافه

چون در کد ، هیچ تاثیری نداره ، بهتره که تبدیل به آرایه ای از double نشه . یعنی من این رو بیشتر میپسندم :



foreach (double item in myArray)