در قسمت قبلی زنگ سیشارپ، در حل تمرین شمارهی ۱۴، توانستید برای هر هنرمند آلبوم ذخیره کنید، هنرمند را حذف کنید و آلبومهای ذخیره شده را مشاهده کنید. همچنین به تفاوت == و متد ()Equals پی بردید و اندکی با namespace آشنا شدید. در این قسمت در مورد Operator Overloading صحبت خواهیم کرد و سپس به ادامهی حل تمرین شماره ۱۴ میپردازیم.
Operator Overloading
سیشارپ به شما اجازه میدهد operator (عملگر) هایی تعریف کنید که مرتبط به کلاسهایی است که خودتان میسازید. به این پروسه، operator overloading گفته میشود. با overload کردن یک operator، شما کاربرد آن operator را به کلاس خودتان اضافه میکنید. تاثیری که این operator روی کلاس شما میگذارد کاملاً تحت کنترل خودتان است و ممکن است برای هر کلاس متفاوت باشد. بهعنوان مثال، کلاسی که یک لیست پیوندی تعریف میکند، ممکن است از عملگر + برای افزودن یک شیء به انتهای لیست، استفاده کند. کلاسی که stack را اجرا میکند، ممکن است از عملگر + برای افزودن یک شیء به بالای پشته، استفاده کند. کلاسی دیگر ممکن است از عملگر + بهطور کاملاً متفاوت استفاده کند.
هنگامیکه یک عملگر overload میشود، معنای واقعی خودش را از دست نمیدهد. بلکه فقط کاربرد آن به یک کلاس افزوده میشود. بنابراین (بهعنوان مثال) overload کردن عملگر + برای افزودن یک شیء به انتهای لیست پیوندی، دلیل نمیشود که عملکرد آن operator برای جمع کردن دو عدد صحیح تغییر کند.
مزیت اصلی operator overloading این است که به شما اجازه میدهد بهطور یکپارچه، یک کلاس جدید را در محیط برنامهنویسی خود، ادغام کنید. این ویژگی که به آن type extensibility میگویند، یکی از بخشهای مهم یک زبان برنامهنویسی شیگرا مثل سیشارپ است. هنگامیکه operator ها برای یک کلاس تعریف میشوند، میتوانید آن operator را روی اشیای کلاس مربوطه، اعمال کنید. این نکته قابل ذکر است که operator overloading یکی از قدرمندترین ویژگیهای سیشارپ است.
اصول Operator Overloading
Operator overloading شباهت زیادی با Method overloading دارد. برای overload کردن یک عملگر، از کلمهی کلیدی operator برای تعریف یک operator method استفاده میکنیم که برای یک عمل خاص، مربوط به کلاس خودش، تعریف میشود.
دو حالت از operator method وجود دارد: unary operators (عملگرهای تکی) و binary operators (عملگرهای دوتایی). فرم کلی هرکدام را در زیر میبینید:
// General form for overloading a unary operator public static ret-type operator op(param-type operand) { // operations } // General form for overloading a binary operator public static ret-type operator op(param-type1 operand1, param-type1 operand2) { // operations }
در اینجا، عملگری که آن را overload میکنید، مثل + یا / ، جایگزین op میشود. ret-type مشخص کنندهی نوع مقداری است که return خواهد شد. اگرچه return type میتواند از هر نوعی باشد اما اغلب از نوع همان کلاسی است که operator در آن overload میشود. این ارتباط (یکسان بودن return type با جنس کلاس) باعث راحتی استفاده از عمگرهای overload شده میشود. برای unary operator ها، عملوند در قسمت operand قرار میگیرد. برای binary operator ها، عملوندها در قسمت operand1 و operand2 قرار خواهد گرفت. توجه داشته باشید که operator method ها باید هم public و هم static باشند.
در unary operator ها، نوع عملوند (operand) باید با نوع کلاسی که operator در آن تعریف میشود، یکسان باشد. بنابراین نمیتوانید operator های سیشارپ را برای اشیایی که خودتان نساختهاید، تعریف کنید. برای مثال، نمیتوانید مجدداً عملگر + را برای int و string تعریف کنید. نکتهی دیگر اینکه، operator parameters نباید از ref وout استفاده کنند.
برای اینکه بیشتر با operator overloading آشنا شوید، مثالی خواهیم زد که در آن binary operator های + و – را overload میکنیم. برنامه زیر کلاسی به اسم TwoD دارد که مختصات دوبعدی یک شیء را نگهداری میکند. عمگر + که آن را overload کردهایم، مختصات یک شیء TwoD را با یک شیء دیگر TwoD جمع میکند. عملگر – نیز مختصات یک شیء را از دیگری کم میکند.
using System; // A two-dimensional coordinate class. class TwoD { private int X, Y; // 2-D coordinates // Constructors public TwoD() { X = 0; Y = 0; } public TwoD(int x, int y) { this.X = x; this.Y = y; } // Overload binary + public static TwoD operator +(TwoD ob1, TwoD ob2) { TwoD result = new TwoD(); result.Y = ob1.Y + ob2.Y; result.X = ob1.X + ob2.X; return result; } // Overload binary - public static TwoD operator -(TwoD ob1, TwoD ob2) { TwoD result = new TwoD(); result.Y = ob1.Y - ob2.Y; result.X = ob1.X - ob2.X; return result; } public void Show() { Console.WriteLine("X: {0} Y: {1}", this.X, this.Y); } } class TwoDDemo { static void Main() { TwoD a = new TwoD(45, 30); TwoD b = new TwoD(15, 13); TwoD c; Console.Write("Here is a: "); a.Show(); Console.Write("Here is b: "); b.Show(); c = a + b; Console.WriteLine(); Console.WriteLine("After add operator: "); c.Show(); c = a - b; Console.WriteLine(); Console.WriteLine("After subtract operator: "); c.Show(); } }
هنگامیکه دو شیء از نوع TwoD توسط عملگر + باهم جمع میشوند، مقدار مختصات مربوطهشان، همانطور که در ()+operator میبینید، باهم جمع میشود. توجه داشته باشید که این متد مقدار عملوندهایش را تغییر نمیدهد، بلکه یک شیء جدید از نوع TwoD که حاصل این جمع را در خودش دارد توسط متد، return میشود. برای اینکه بفهمید چرا عملگر + عملوندهای خودش را تغییر نمیدهد، عملگر استاندارد ریاضی + که در آن (مثلاً) ۱۰ + ۱۲ میکنید را در نظر بگیرید. حاصل این جمع ۲۲ است اما ۱۰ و ۱۲ توسط آن عوض نمیشوند. البته هیچ قانونی وجود ندارد که جلوی عملگر overload شده را بگیرد تا مقدار عملوندهایش را تغییر ندهد، اما بهتر است وقتیکه یک عملگر overload میشود، معنای اصلی خودش را نیز حفظ کند.
توجه کنید که ()+operator یک شیء از نوع TwoD را return میکند. اگرچه این متد میتواند نوعهای دیگری که در سیشارپ مجاز هستند را نیز return کند اما return کردن یک شیء از نوع TwoD به عملگر + اجازه میدهد تا بتواند در عبارتهای ترکیبی مثل a + b + c مورد استفاده قرار گیرد. در اینجا a + b نتیجهای از جنس TwoD تولید میکند که میتوانیم آن را در c ذخیره کنیم.
نکتهی مهم دیگری در اینجا وجود دارد. وقتیکه مختصات اشیاء، درون ()+operator باهم جمع میشوند، حاصل جمع x و y، عدد صحیح است. درواقع، عملگر + که برای اشیای TwoD، overload شده است تاثیری بر عملگر + که روی اعداد صحیح اعمال میشود ندارد.
اکنون به ()-operator توجه کنید. عملگر – مثل عملگر + کار میکند بهاستثنای اینکه ترتیب پارامترها در اینجا اهمیت دارد و پارامترها جابهجاییپذیر نیستند (یعنی A-B با B-A متفاوت است). برای همهی binary operator ها، پارامتر اول برای عملوند سمت چپ و پارامتر دوم برای عملوند سمت راست است. بنابراین هنگامیکه ورژن overload شدهی operator های جابهجاییناپذیر را اجرا میکنید باید بهیاد داشته باشید که کدام عملوند سمت چپ و کدام یک سمت راست قرار دارد. (ادامهی این بحث را در قسمت بعد دنبال کنید)
ادامهی حل تمرین شماره ۱۴
اگر به یاد داشته باشید یکی از عملیات این برنامه اضافه کردن تکآهنگ برای هر هنرمند بود. برای افزودن تکآهنگ برای هر خواننده ما از متد زیر که در کلاس Artist قرار دارد، استفاده میکنیم:
public bool AddSingleTune(Tune tune) { if (SingleTuneCounter < SingleTunes.Length) { SingleTunes[SingleTuneCounter] = tune; SingleTuneCounter++; return true; } return false; }
در این متد یک متغیر بهاسم SingleTuneCounter داریم که شمارنده و کنترلکنندهی تعداد تکآهنگهای ذخیره شده است. مقدار این متغیر را در constructor برابر با صفر قرار داده و پس از افزودن هر تکآهنگ، مقدار این متغیر را یک واحد افزایش میدهیم. این متد همچنین یک شیء از جنس Tune دریافت کرده و آن را در آرایهای که برای ذخیره تکآهنگها در نظر گرفته شده است، ذخیره میکند.
از طرف دیگر در متد UI باید یک شیء Tune بهوجود آوریم و در نهایت شیء ساخته شده را به متد ()AddSingleTune پاس بدهیم تا در آرایه مربوطه ذخیره شود. نکته قابل توجه اینجاست که باید شیء Tuneرا از طریق دومین constructor آن که برای تکآهنگها در نظر گرفته بودیم، بسازیم. به کلاس Tune و constructor های آن مجدداً توجه کنید:
class Tune { private string TuneName; private string Composer; private string Songwriter; private string TuneOwner; private string TuneGenre; private ushort TuneYear; private string Path; // Constructor for album tunes public Tune( string tuneName, string tuneGenre, string composer, string songwriter, string path ) { TuneName = tuneName; TuneGenre = tuneGenre; Composer = composer; Songwriter = songwriter; Path = path; } // Constructor for single tunes public Tune( string tuneName, string tuneGenre, string composer, string songwriter, ushort tuneYear, Artist artist, string path ) : this(tuneName, tuneGenre, composer, songwriter, path) { TuneOwner = artist.GetArtistNameAndFamily(); TuneYear = tuneYear; } }
به دومین constructor دقت کنید. در این constructor ما علاوهبر مواردی که در constructor قبلی وارد کردیم، یک شیء از جنس Artist و سال انتشار را نیز باید وارد کنیم. بنابراین برای ساخت تکآهنگ از این constructor استفاده کردهایم.
همچنین برای دیدن تکاهنگهای ذخیره شده از متد زیر استفاده میکنیم:
public void ViewSingleTunes() { for (byte b = 0; b < SingleTunes.Length; b++) { if (SingleTunes[b] == null) continue; Console.WriteLine(SingleTunes[b].GetTuneName()); } }
در متد بالا، تکآهنگها مستقیماً نمایش داده میشوند اما شاید نخواهیم که تکآهنگها به این صورت (در هر خط یک تکآهنگ) نمایش داده شود. شاید بخواهیم در قسمتهای مختلف برنامه این تکآهنگها را بهصورتهای متفاوتی نمایش دهیم. بنابراین بهجای نمایش مستقیم آنها، یک متد مینویسیم و آرایهای از تکآهنگهای موجود را return میکنیم تا هرجای برنامه که لازم بود این تکآهنگها را آنطور که خواستیم نمایش دهیم.
public Tune[] GetSingleTunes() { return SingleTunes; }
در متد بالا تکآهنگهای ذخیره شده return میشود و سپس در متد UI هرطور که خواستیم آنها را نمایش میدهیم.
تا اینجا مراحل افزودن (هنرمند، آلبوم، تکآهنگ) و دیدن چیزهایی که اضافه کردید را به اتمام رساندید. اکنون وقت آن رسیده است که بتوانید موارد ذخیره شده را ویرایش کنید. در مرحلهی ویرایش، بایستی بتوانیم هنرمند، آلبوم و تکآهنگهای او را ویرایش (Edit) کنیم.
اگر پروژه قسمت قبل را دانلود کرده باشید، برای این منظور یک گزینه به اسم Edit برای هر هنرمند در نظر گرفته بودیم. هنگامیکه Edit انتخاب میشود، باید سه گزینه اصلی برای Edit نمایش داده شود که در مورد دو گزینه در اینجا بحث خواهیم کرد. گزینههای Edit name and family و Edit Albums و Edit single tunes گزینههایی هستند که برای این منظور در نظر گرفتیم.
با گزینهی Edit name and family شروع میکنیم. در اینجا شما باید نام و نامخانوادگی هنرمند را ویرایش کنید. برای این منظور تنها کافی است که نام و نامخانوادگی جدید را از کاربر دریافت، سپس آن را جایگزین نام و نامخانوادگی قبلی کنید. برای ویرایش نام و نامخانوادگی از متد زیر استفاده میکنیم:
public void EditNameAndFamily(string name, string family) { ArtistName = name; ArtistFamily = family; }
این متد که در کلاس Artist قرار دارد، نام و نامخانوادگی جدید را دریافت و آن را جایگزین قبلی میکند.
در مرحلهی بعد قصد داریم که تکاهنگها را ویرایش کنیم. برای ویرایش تکآهنگ گزینههای زیر را مد نظر داریم:
تنها کاری که در اینجا باید انجام دهید این است که توسط یک switch همهی این گزینهها را وارد و یکییکی ویرایش کنید:
switch (choice) { case "1": // Edit name break; case "2": // Edit genre break; case "3": // Edit composer break; case "4": // Edit songwriter break; case "5": // Edit year break; case "6": // Edit path break; case "7": // Delete break; case "8": // Back break; }
برای بهانجام رساندن این ویرایشها، در کلاس Tune متدهایی زیر را در نظر گرفتهایم:
// Methods (Get and Set) public string GetTuneName() { return TuneName; } public void SetTuneName(string name) { TuneName = name; } public string GetComposer() { return Composer; } public void SetComposer(string composer) { Composer = composer; } public string GetSongwriter() { return Songwriter; } public void SetSongwriter(string songwriter) { Songwriter = songwriter; } public string GetTuneGenre() { return TuneGenre; } public void SetTuneGenre(string genre) { TuneGenre = genre; } public ushort GetTuneYear() { return TuneYear; } public void SetTuneYear(ushort year) { TuneYear = year; } public string GetTunePath() { return Path; } public void SetPath(string path) { Path = path; }
بنابراین برای ویراش نام یک تکآهنگ کافی است که نام جدید را از کاربر دریافت و آن را توسط متد ()SetTuneName جایگزین نام قبلی کنیم. بقیهی فیلدها نیز به همین ترتیب ویرایش میشوند. برای delete کردن یک تکآهنگ کافی است که آن خانه از آرایه که تکآهنگ مورد نظر در آن قرار دارد را برابر با null قرار دهید. برای این منظور از متد زیر استفاده میکنیم:
public void RemoveSingleTune(int index) { SingleTunes[index] = null; }
در قسمت بعد، ویراش album و play کردن آهنگها را توضیح خواهیم داد. پروژه این تمرین را میتوانید از اینجا دانلود کنید. قابل ذکر است که پروژه، اکنون تا ویرایش تکآهنگها برای دانلود قرار داده شده است و در قسمت بعد میتوانید نسخه نهایی و کامل آن را دانلود کنید.
داوود
21 May 2013
سلام مسعود جان؛
دستت درد نکنه از اینکه درس سی و یکم رو قرار دادی.
فقط یک موضوع رو میخواستم ازت درخواست کنم که اگه امکان پذیر باشه انجام بدی.
چون من مطالب فایل pdf رو چاپ می کنم که بتونم تو جاهای دیگه م که به کامپیوتر دسترسی ندارم؛مطالعه کنم از قسمت بیست و پنجم به بعد background قسمت کدها رو حسابی سیاه کردی که این مورد باعث استفاده خیلی بیشتری از جوهر پرینتر میشه.
قبل از اون قسمت و تا قسمت بیست و چهارم پس زمینه کدها به نوعی خاکستری بود که هم زیباتر بود و هم باعث کمتر مصرف شدن جوهر می شد.
ممنون میشم اگه این مورد رو به روال قبل تغییرش بدی.
ببخشید از اینکه سرتون رو درد آوردم.
ممنونم
مسعود درویشیان
21 May 2013
سلام. خواهش میکنم
باشه انشالله از قسمت بعد همون خاکستری میکنم که واسه پرینت هم مناسب باشه.
ممنون از پیشنهادت :)
مصطفی
21 May 2013
با عرض سلام و خسته نباشید به آقا مسعود گل
با این آموزش های فوق العاده که واقعا باید بهت بگیم دست مریزاد و خسته نباشید
اما سوال من ، مسعود جان این هستش که شما برای نوشتن این آموزش ها از چه منبعی استفاده می کنی( اگه ممکنه منابعی که برای آموزش سی شارپ ازشون استفاده می کنی رو واسم نام ببر)
بازم ازت ممنونم بخاطر این آموزش های فوق العادت
مسعود درویشیان
21 May 2013
سلام، خواهش میکنم
برای نوشتن این آموزشها فقط از یه منبع استفاده نمیکنم. مقالات مختلف، تجربههای شخصی و غیره.
حالا اسم چندتا کتاب که خیلی مفید هستن و ازشون کمک میگیرم رو مینویسم برات:
C# 4.0 The Complete Reference
Microsoft Visual C# 2010 An Introduction to Object-Oriented Programming, 4th Edition
Essential C# 4.0 (3rd Edition) (Microsoft .NET Development Series)
Professional C# 4.0 and .NET 4
#FLUENT C
C# 4.0 Unleashed
harry
21 May 2013
سلام.
خسته نباشی آقای مسعود
سوالم اینه که اگه بخوام تو C# مقادیری رو دخیره کنم که نمیدونم طول این مقادیر چقدره و بعدا هم بتونم به همون ترتیب بهشون دسترسی داشته باشم باید چیکار کنم؟
اگه بتونید راهنماییم کنید ممنون میشم………
مسعود درویشیان
21 May 2013
سلام. منظورتون مثل ذخیره کردن توی خونههای آرایهست؟
harry
21 May 2013
بله ولی نمیدونم طولش چقدر میشه!؟
البته به غیر از لیست پیوندی
مسعود درویشیان
21 May 2013
البته در این مورد توی مقالات آینده صحبت خواهیم کرد ولی اگه میخوای زودتر آشنا بشی پیشنهاد میکنم این لینک رو ببینی.
harry
21 May 2013
واقعا ممنون، خیلی گلی
راستی من دارم یه پروژه مینویسم واسه درس شبیه سازی، میتونم رو کمکت حساب کنم؟ خواهش می کنم!!!
مسعود درویشیان
21 May 2013
خواهش میکنم. 100% رو کمک من حساب نکن ولی تا اونجا که بتونم راهنماییت میکنم.
رها امیر چرمهینی
21 May 2013
با سلام
کامل و مفید بود
خسته نباشید
اگه امکان داره در مورد قالبهای ریسپانسیو و ترنزیشن در css یه مطلب کامل واسه مبتدیانی چون من هم قرار بدین
علاقه شدیدی به طراحی ریسپانسیو و ساخت slideshow در css پیدا کردم اما منبعی که واسه مبتدی ها باشه پیدا نکردم
از طریق سرچ در همین موضوع هم سایت شما رو پیدا کردم اما محتوای مطالب این زمینه بسیار بالا بود و بصورت خلاصه نویسی نوشته شده بود
اگر دراین خصوص مطلب روانی قبلا نوشتید لینک کنید در همین قسمت
اگر هم ننوشتید و منبع خوبی میشناسین لطفا معرفی کنین
با تشکر وارزوی توفیق
مسعود درویشیان
21 May 2013
از foundation واسه responsive کردن استفاده کن.
رها امیر چرمهینی
21 May 2013
سلام
از لطف و راهنمایی شما سپاسگذارم
شاد وپیروزو سربلند باشید
داوود
21 May 2013
سلام مجدد به آقا مسعود عزیز؛
وقتت بخیر؛
مسعود جان چون دیدم معمولا اگه تو قسمت جدیدی که ارائه میشه سوالمون رو بپرسیم زودتر به جواب می رسیم ترجیح دادم ادامه سوال قبلی رو اینجا بپرسم.
مسعود جان من در این برنامه میخواستم با استفاده از params تعداد اعداد دلخواه رو از کاربر بگیرم و میانگین رو نشون بدم.
برنامه رو بدین نحو نوشتم:
فقط یک سوال برام باقی مونده و اونهم اینه که چرا خطی رو که comment کردم(خط 28) اگه بخوام استفاده کنم تا دیگه از متغیر k کمک نگیرم همون ابتدا و بعد از گرفتن فقط یک عدد ازم اشکال میگیره و برنامه اجرا نمیشه؟ بعلت اینه که طولش مشخص نیست؟ این هم متن پیغامی هست که نشون میده. System.IndexOutOfRangeException
مسعود درویشیان
21 May 2013
داوود جان تو این مثالت کلاً از params استفاده نکردی. فک کنم درست متوجهش نشدی
وقتی داری از متد ()Average استفاده میکنی یا باید بهش یه آرایه بدی:
یا باید دستی بهش عدد بدی:
اما اصلا از ویژگی params استفاده نکردی!
من همین مثال میانگین گرفتن رو مجدداً برات نوشتم:
هرجاش مشکل داشتی بگو تا کامل توضیح بدم :)
داوود
21 May 2013
ممنونم عزیزم؛ الان نگاه می کنم و اگه کمکی خواستم حتما مزاحمت میشم.
ببخشید.
داوود
22 May 2013
مسعود جان سلام؛
آقا ببخشید چون میخواستم ببینم خودم میتونم بنویسم یا نه با اجازه شما و طبق توضیحی که دادی و فهمیدم که اصلا از params استفاده نکردم اومدم و فقط کلاس اولیه رو از شما نگاه کردم و بقیه رو سعی کردم خودم بنویسم. یعنی فقط کلاس اولیه رو نگاه کردم و مابقی رو اصلا نگاه نکردم تا ببینم میتونم انجامش بدم یا نه.
ببین مسعود جان تا اینجا رو از کد شما استفاده کرده و بهره گرفتم:
و مابقی رو هم خودم نوشتم که اینها هستن:(البته فعلا کاربر نمیتونه بگه چند تا عدد فقط میتونه به تعدادی که ما تعیین کردیم عدد وارد کنه که فعلا 8 تاست):
در مجموع کل برنامه بدین شکل میشه:
ممنون و متشکرم.
مسعود درویشیان
22 May 2013
خوبه، درسته :)
harry
23 May 2013
سلام خوبی؟
یه سوال اگه بخوام یه آرایه با 4 تا ستون و 1 سطر تعریف کنم بعد تو اجرای برنامه تو یه حلقه هر بار یه واحد به سطرهای اون اضافه کنم باید چیکار کنم؟؟؟
اگه بتونی کدش رو برام بذاری کلی لطف میکنی!!!
مصطفی
26 May 2013
مسعود جان ممنون از این همه لطف و زحمتی که می کشی؟
ما که پاک خجالت زده شما با این آموزش های عالیتون هستیم.
ما که کاری واست متاسفانه نمی تونیم انجام بدیم ولی انشاءالله خدا پاداش این همه زحمت بی منت و بی دریغت رو بده
من که از آموزش هات خیلی راضیم
در انتها بازم باید بگم که آقا مسعود ما دربست مخلص این مرام و معرفت هستیم
مسعود درویشیان
26 May 2013
قربانت مصطفی جان :) مرسی که مقالات رو دنبال میکنی
داوود
30 May 2013
سلام مسعود جان؛
در درست بیست و ششم و در ابتدای درس کدی بدین شکل گذاشتی:
و در زیر همین کد توضیحات مربوط به کد رو شرح دادی.
حالا مسعود جان من اگه بیام و قسمت پایین همین کد رو بدین شرح تغییرش بدم:
چرا این خط :
نباید محتویات secondperson رو به من نشون بده!(البته نباید نشون بده ولی سوالم همینجاست.)
اولا چرا نمیتونستیم بدون استفاده از شی ء دیگه ای از خود secondperson استفاده کنیم و اصلا از شی دیگه ای کمک نگیریم؟
دوما مگه زمانی که ما یک شی درست می کنیم مثلا firstperson ! خب بعدش که یک شی دیگه از این شی درست می کنیم آیا آدرس firstperson به شی دوم مراجعه نمیکنه؟ یعنی Refrence ش عوض نمیشه؟ تو حافظه این جور وقتها چطوری عمل میشه؟
ببخشید که سوالام زیاد بود.
ممنونم ازت
مسعود درویشیان
1 June 2013
نه ببین داوود جان، اولاً هدف از نوشتن این متد این بود بودم که نشون بدم چطوری از یه متد میتونی یه شیء رو return کنی. دوماً، واسهچی secondPerson باید محتوای firstPerson رو نشون بده؟ اصلاً دلیلی نداره! ما توی متد ()CreateNewPerson یه شیء کاملاً جدا ساختیم که reference مخصوص خودش رو داره (ob reference)
که بعدش تو متد ()Main اومدیم این ob reference رو که از متد ()CreateNewPerson گرفتیم، گذاشتیم توی secondPerson
firstPerson شیء خودش رو داره
secondPerson هم شیء خودش رو داره
و ایندو به هم مربوط نیستند فقط از یه جنس هستند
داوود
2 June 2013
ممنونم مسعود جان؛
توضیحاتت خوب بود.
پس شما برای اینکه secondperson و firstperson از یه جنس باشند اومدین و از روی firstperson ، شی بعدی یعنی secondperson رو ایجاد کردی؟فقط بدلیل اینکه از جنس باشن؟
اگه میخواستیم بدون استفاده از firstperson شی بعدی یا همون secondperson رو با استفاده از همون متد یعنی ()CreateNewPersonایجاد کنیم چی؟ ببخشید مسعود جان اگه سوالم مبتدی هستش.
مسعود درویشیان
2 June 2013
نه! همونطور که میدونی جنس هردوشون Person هست و ما مستقیماً میتونستیم بسازیمش (بدون نیاز به firstPerson)
ولی همونطور که گفتم، هدف این بود که نشون بدم از روی یه شیء دیگه هم میتونی اینکارو انجام بدی، میتونی از یه متد یه شیء return کنی…
داوود
6 June 2013
مرسی مسعود جان و ممنونم ازت؛
اونروز که تست کردم دیدم نمیتونم بدون استفاده از firstperson یک شی جدید و فقط با استفاده از secondperson ایجاد کنم ولی امروز برنامه رو بدین شکل تغییرش دادم و کار کرد.
علت اینکه با این کد کار نمیکنه:
و پیام خطای Use of unassigned local variable ‘second’
رو میده به این خاطر هستش که این شی ء هنوز بوجود نیومده و فضایی رو بهش اختصاص نداده؟
ولی با این کد که استنباط می کنم بخاطر همون موضوع بالا باشه براحتی کار میکنه:
ببخشید که بیشتر وقت شما رو سوالات من میگیره.
ازتون عذرخواهی می کنم.
harry
2 June 2013
سلام مسعود جان.
هر چند سوال آخرمو جواب ندادی ولی خواستم به خاطر منبعی که معرفی کردی تشکر کنم. واقعا عالی بود و کل مشکلاتم حل شد. بازم ممنون………
مسعود درویشیان
2 June 2013
خواهش میکنم، اینم جواب سوال آخر :)
هرجاشو نفهمیدی بگو تا بیشتر توضیح بدم.
harry
3 June 2013
منظورم این نبود ولی به هر حال ممنون حل شد با اون منبعی که معرفی کردی……..
رضا
4 June 2013
ممنون برای وقتی که اختصاص میدید
لطفا بفرمایید کی به مبحث تابع اشاره میکنید؟؟
مسعود درویشیان
4 June 2013
تابع رو که گفتیم رضا جان !
همین متد هست دیگه…
داوود
6 June 2013
سلام مسعود جان؛
من طبق عادت همیشگی دوست دارم قبل از اینکه کد شما رو ببینم؛ ابتدا خودم اقدام به نوشتنش کنم. برای همین یک سوال ازتون داشتم. ببینید در درس بیست و ششم و در همون ابتدای درس و در قسمتی که میخواستیم یک آرایه رو از طریق متد برگردونیمش من یکمی کلنجار رفتم. کد من رو ببینید:
قسمتهایی رو که comment کردم بدین علته که اول داشتم با اونها کار می کردم.
اینهم متن اصلی برنامه:
اولا میخواستم بگم بنظرتون کجای درس رو نفهمیدم که برام مقداری انجامش مشکل بود؟ آیا تو اینجا و در هنگام تعریف متد نمیخواست اونو static بگیرمش؟ نمیخواست از ref یا out استفاده کرد؟
همچنین برای برگردون این آرایه از یه متد دیگه مشکل دارم و اونهم اینه چجوری باید اینکار رو انجام بدم؟
ببینید تو متد دیگه تا اینجاش رو نوشتم ولی بعد از نقطه نمیدونم چی باید بنویسم که بتونم آرایه متد قبلی رو برگردونم.
ممنونم.
داوود
6 June 2013
ضمنا از سایت زیر هم برای انجام دادن متد مربوط به آرایه استفاده کردم.
http://www.dotnetperls.com/array
مسعود درویشیان
11 June 2013
سلام. ببین داوود جان، تو میخوای مثلاً از یه متد یه آرایه رو return کنی، مثلاً به کلاس زیر توجه کن:
اینجا یه آرایه داریم بهاسم Friends که توی constructor بهش مقدار دادیم. بعد از طریق متد ()GetFriends این آرایه رو return کردیم. خوب الان میخوای از این متد که آرایه رو return کرده استفاده کنی. به متد ()Main زیر توجه کن:
اولین کاری که کردیم این هست که اومدیم یه شیء از Person ساختیم تا به متد ()GetFriends دسترسی داشته باشیم. متد ()GetFriends یه آرایه بر میگردونه درسته؟ خوب این آرایه که داره return میشه رو باید بگیریمش دیگه، پس میایم یه string[] myFriends تعریف میکنیم تا اون آرایهای رو که متد ()GetFriends برمیگردونه داخلش ذخیره کنیم. آخرم که با یه حلقه، عناصر آرایه رو نمایش دادیم :)
اگه بازم توضیح بیشتری نیازه حتماً بگو تا بیشتر توضیح بدم
sanaz
9 June 2013
سلام من اگه بخوام از قسمت ۱زنک c# رو دانلود کنم باید چیکار کنم؟
مسعود درویشیان
10 June 2013
از این لینک میتونید مقالات زنگ سیشارپ رو قسمت به قسمت دانلود کنید.
داوود
11 June 2013
مسعود جان؛ چون دیدم شاید سرت شلوغ باشه و وقت نکنی یکم دیگه با کد ور رفتم و اینجوری تقریبا به اون خواسته ای که میخواستم رسیدم، یعنی یک آرایه رو از یه متد دیگه فراخوانیش کنیم.
کدهام تقریبا مشابه کدهای قبلیه ولی ببین درسته؟ اگه درست بود؛ بهم بگو تا دیگه نیازی نباشه وقت خودت رو جهت پاسخ به پستهای قبلیم صرف کنی:
اینهم کدهای مربوط به تعریف آرایه ، مقدار دهی به اون و متد بازگردونی اون:
در واقع کار اصلی که کردم تعریف آرایه به صورت public ودر ابتدای کلاس بود و همچنین اضافه کردن foreach برای خوندن آرایه مورد نظر.
ممنون میشم اگه نظرتونو در صورت داشتن وقت بدین.
ببخشید.
مسعود درویشیان
11 June 2013
الان همهچی خوبه، فقط یه مشکلی هست، شما اول اومدی نوشتی:
که یعنی یه شیء جدید توی حافظه بهوجود آوردی
بعدش نوشتی:
یعنی یه شیء دیگه دوباره درست کردی باز وصلش کردی به رفرنس second (و عملاً اون شیء قبلی که درست کردی بیهوده بود)
بهتر بود توسط first اینکارو انجام میدادی یعنی:
داوود
11 June 2013
ممنونم ازت؛ خودت خوبی (:
ایرادی رو هم که گرفتید کاملا حق با شماست؛ ولی راستش رو بخواین اونها فقط جنبه تمرین و آزمایش داشتن عزیزم
مسعود درویشیان
11 June 2013
آره متوجهام، کلاً گفتم که در جریان باشی
hamzeh
13 June 2013
با سلام خدمت آقا مسعود گل
آقا مسعود اگ میشه یه زنگasp.net رو راه ندازی کنید که آموزش asp.net توش باسه . ممنون از آموزش های خوبت.خسته نباشی داداش….
مسعود درویشیان
13 June 2013
حالا ما فعلاً زنگ سیشارپ رو به پایان برسونیم :)
Reza
13 June 2013
مگه زبان برنامه نویسی پایانی داره!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
مسعود درویشیان
13 June 2013
برنامهنویسی پایان نداره ولی زنگ سیشارپ داره :دی
مصطفی
13 June 2013
با عرض سلام خدمت آقا مسعود گل گلاب تو گلدون
ببخشید مزاحم شدم ولی می خواستم بدونم که آموزش جدید رو انشاءالله کی قرار میدید و ما را مستفیز می فرمایید.
ممنونم
مسعود درویشیان
13 June 2013
حداکثر تا فردا شب
داوود
13 June 2013
سلام آقا مسعود گل و عزیز؛ خوبی؟
میخواستم بپرسم میتونیم سوالات css مون رو از شما بپرسیم؟ فکر می کنم دستی هم تو طراحی دارید ماشاءالله ولی به روی خودتون نمیارین.
میشه یه آموزش خوب در خصوص تبدیل قالبهای psd به html یا معرفی کنید یا بعدها پس از زنگ#C خودتون قرار بدین؟
ممنونم مسعود جان
مسعود درویشیان
13 June 2013
سوالات css رو اگه برام ایمیل کنی بهتره که اینجا با سوالای سیشارپ قاطی نشه
حالا زنگ سیشارپ که تموم شد واسه بعدش هم یه تصمیم میگیریم :)
ممنون از پیشنهادت
داوود
13 June 2013
مرسی مسعود جان؛ همچنین از اینکه زود جواب میدی یه تشکر ویژه هم ازت دارم؛ هرچند که اگه دیر هم جواب بدی ما رو شرمنده خودت کردی و هیچ توقع بیجایی از شما نداریم.
ولی مسعود جان اونجوری ممکنه ایمیلت پر بشه.
مسعود درویشیان
13 June 2013
ممنون اشکال نداره داوود جان، خالیش میکنیم :دی
master
13 June 2013
آقا ممنون از وبسایتت.جانه من asp.net هم آموزش بده.دمت گرم
omid
4 August 2013
ba arze salam va khaste nabashid… jesaratan soali dashtam . injaro behem moarefi kardan goftam mitoonam javabamo begiram…
ایده کلی روش fluent برای کار با اشیای کلاسها چیست ؟
jesaratan tozihe kamel mikham baraye inke befahmam va inke agar lotf konid alave bar tozih manbaii ham zekr befarmaiid mamnoon misham, ba tashakor
مسعود درویشیان
4 August 2013
توی مهندسی نرمافزار، fluent interface یه روش پیادهسازی API شیء گراست و هدفش این هست که کد خوانایی بیشتری داشته باشه
برای اطلاع بیشتر + و + و + لینک رو ببینید
marzi
6 June 2014
سلام
آیا در سی شارپ اشاره گر به اشاره گر داریم؟؟؟
چطور؟؟؟
مسعود درویشیان
6 June 2014
http://www.developerfusion.com/article/84447/pointers-on-pointers/
http://limbioliong.wordpress.com/2012/04/17/how-to-implement-pointer-to-pointer-in-c-without-using-unsafe-code/
nadia
25 October 2014
salam,mamnon az etela’ate mofidetoon aliii bod,,faghat ghesmate 16 ro man nadaram k betonam bekhonam
sadat
5 November 2014
سلام من یه سوال مشابه سوالات دوستان دارم ولی بدون استفاده از params و هیچ چیز دیگه چون استادمون هنوز اینارو بهمون یاد نداده و نباید استفاده کنیم
باید یه برنامه بنویسم که یه آرایه از نوع اینتیجر تعریف کنم و با استفاده از تابع میانگین بگیره
یعنی در فرمم یه textbox دارم که خاصیت مولتی لاینش true هست وکاربر هر تعداد که دلش بخواد عدد وارد میکنه و روی دکمه که زد میانگین رو روی برچسب نشون بده
لطفا راهنمایی کنید چون من تا یکشنبه وقت دارم
sadat
6 November 2014
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace miyangin
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
// int[] names = Convert.ToInt16(textBox1 .Lines );
String[] s = textBox1.Lines;
int[] names = new int[s.Length];
int avg1 = avg(names);
label1.Text = Convert.ToString(avg1);
}
catch (Exception)
{
MessageBox.Show(“hoshdar”);
}
}
int avg(int[] names)
{
int sum = 0;
for (int i = 0; i <= names.Length; i++)
{
sum = sum + names[i];
}
int avrag = sum / (names.Length);
return avrag;
}
}
}
sadat
6 November 2014
این برنامه منه لطفا اگه کسی میتونه راهنمایی کنه چون جواب نمیده
فرهاد
22 July 2015
دیگه راهنمایی ها تموم شده فکر کنم :(
من متوجه operator overloading نشدم
مثال مربوط به این قسمت خیلی TwoD داشت اصلا متوجه نشدم کار مفیدش چیه و چرا انقدر مهمه :(
لطفا please
Mohammad mahdi
23 December 2016
عالی بود واقعا.
بینهایت سپاسگزارم..🌹
Sh
21 April 2019
سلام.ببخشید میخواستم برای نوشتن یک برنامه در c# کمکم کنید.
باید برنامه ای بنویسیم که میانگین را بر اساس دروس زیر محاسبه و چاپ کند.
ریاضی2واحد-تاریخ2واحد و فیزیک 2واحد(نمره هر درس از کاربر دریافت شود)
توروخدا کمکم کنین واقعا توش گیر کردم