در قسمت قبل با return کردن object و overloading آشنا شدید. در این قسمت از زنگ سیشارپ قصد داریم به مباحث مهم stack ،heap ،value types ،reference types، boxing و unboxing بپردازیم و همچنین optional arguments، named arguments، garbageCollection و object initializers را مورد بحث و بررسی قرار دهیم.
هنگامیکه یک متغیر تعریف میکنید، دقیقاً چه اتفاقی میافتد؟
هنگامیکه شما در اپلیکیشنهای NET. یک متغیر تعریف میکنید، قسمتی از حافظهی RAM برای این منظور اختصاص داده میشود. این قسمت از حافظه، شامل سه چیز است: نام متغیر، data type متغیر و مقدار متغیر.
با توجه به data type، متغیر شما در قسمتهای متفاوتی ذخیره میشود. دو نوع تخصیص حافظه وجود دارد که یکی stack memory و دیگری heap memory است. برای اینکه بهتر با stack و heap آشنا شوید به کد زیر و شرح آن توجه کنید:
public void Method1() { // line 1 int x = 2; // line 2 int y = 5; // line 3 MyClass ob = new MyClass(); }
هنگامیکه line 1 اجرا میشود، کامپایلر مقدار کمی از حافظه را در stack برای این منظور اختصاص میدهد. stack مسئول پیگیری حافظهی مورد نیاز (در حال اجرا) در اپلیکیشن شما است. همانطور که پیش از این با نحوهی ذخیرهسازی اطلاعات در stack آشنا شدید، stack عملیات Last In First Out را اجرا میکند و هنگامی که line 2 اجرا میشود، متغیر y در بالای stack ذخیره خواهد شد. در line 3 ما یک شیء بهوجود آوردهایم و در اینجا اندکی داستان متفاوت میشود. پس از اینکه line 3 اجرا شد، متغیر ob در stack ذخیره میشود و شیءای که ساخته شده در heap قرار میگیرد. نکته دقیقاً همینجاست که reference ها در stack ذخیره میشوند و عبارت MyClass ob حافظه را برای یک شیء از این کلاس اشغال نمیکند. این عبارت تنها متغیر ob را در stack قرار میدهد (و به آن مقدار null میدهد) و هنگامیکه کلمهی کلیدی new اجرا میشود، شیء این کلاس در heap ذخیره خواهد شد. در نهایت هنگامیکه برنامه به انتهای متد میرسد، متغیرهایی که در stack بودند همهگی پاک میشوند. توجه کنید که پس از به پایان رسیدن متد چیزی از heap پاک نمیشود بلکه اشیای درون heap بعداً توسط garbage collector پاک خواهند شد. در مورد garbage collector در انتهای این مقاله صحبت خواهیم کرد.
ممکن است برایتان سوال باشد که چرا stack و heap ؟ نمیشود همه در یکجا ذخیره شوند؟ اگر با دقت نگاه کنید میبینید که data type های اصلی (value types)، پیچیده و سنگین نیستند. آنها مقادیر تکی مثل int i = 5 را نگه میدارند در حالیکه object data types یا reference types پیچیدهتر و سنگینتر هستند، آنها به اشیای دیگری رجوع میکنند. به عبارت دیگر، آنها به چندین مقدار رجوع میکنند (زیرا اشیاء میتوانند شامل مقادیر زیادی از فیلد و متد و… باشند) که هرکدام از آنها باید در حافظه ذخیره شده باشد. اشیاء به dynamic memory و data type های اصلی (value types) به static memory نیاز دارند. اگر اطلاعات شما نیازمند dynamic memory باشد، در heap ذخیره میشود، اگر نیازمند static memory باشد، در stack ذخیره خواهد شد.
Value types و Reference types
اکنون که با مفاهیم stack و heap آشنا شدید بهتر میتوانید مفهوم value types و reference types را درک کنید. Value type ها تمام و کمال در stack ذخیره میشوند، یعنی هم مقدار و هم متغیر همهگی یکجا هستند اما در reference type متغیر در stack است درحالیکه object در heap قرار میگیرد و متغیر و شیء به هم متصل میشوند (متغیر به شیء اشاره میکند).
در زیر، data type ای از جنس int داریم با اسم i که مقدارش به متغیری از نوع int با اسم j اختصاص داده میشود. این دو متغیر در stack ذخیره میشوند. هنگامیکه مقدار i را به j اختصاص میدهیم، یک کپی (کاملاً جدا و مجزا) از مقدار i به j داده میشود و به عبارت دیگر هنگامی که یکی از آنها را تغییر دهید، دیگری تغییر نمییابد:
هنگامیکه یک شیء میسازید و reference آن را با یک reference دیگر مساوی قرار میدهید، آنگاه هر دوی این reference ها به یک شیء رجوع میکنند و تغییر هر کدام از آنها باعث تغییر شیء میشود زیرا هردو reference به یک شیء اشاره میکنند.
به مثال زیر توجه کنید:
using System; class Person { public string Name; public string Family; public void Show() { Console.WriteLine(Name + " " + Family); } } class Myclass { static void Main() { Person ob1 = new Person(); Person ob2 = ob1; ob1.Name = "Nicolas"; ob1.Family = "Cage"; Console.Write("ob1: "); ob1.Show(); Console.Write("ob2: "); ob2.Show(); Console.WriteLine(); ob2.Name = "Ian"; ob2.Family = "Somerhalder"; Console.Write("ob1: "); ob1.Show(); Console.Write("ob2: "); ob2.Show(); } }
همانطور که میبینید، ابتدا یک شیء ساخته و سپس reference دیگری تعریف کردهایم و نهایتاً آنها را مساوی هم قرار دادهایم. توجه کنید که برای ob2 شیء جدید تعریف نکردهایم بلکه ob2 به همان شیءای رجوع میکند که ob1 به آن رجوع میکند. بنابراین تغییر هرکدام بر روی شیء تاثیر میگذارد. همانطور که میبینید، ob1.Name و ob2.Family در ابتدا برابر با Nicolas Cage است سپس با تغییر ob2.Name و ob2.Family به Ian Somerhalder مقادیر فیلدهای ob1 نیز تغییر خواهند کرد. به شکل زیر توجه کنید:
Boxing and Unboxing
بهطور خلاصه، وقتیکه یک مقدار value type را تبدیل به reference type میکنید، در واقع اطلاعات را از stack به heap میبرید و هنگامیکه یک مقدار reference type را تبدیل به value type میکنید، اطلاعات را از heap به stack میبرید. این رفت و برگشت اطلاعات از stack به heap روی performance (کارایی، سرعت اجرا) برنامه تاثیر میگذارد. فرستادن اطلاعات از stack به heap در اصطلاح boxing و فرستادن اطلاعات از heap به stack در اصطلاح unboxing نامیده میشود.
استفاده از boxing و unboxing باعث افت performance میشود بنابراین تا آنجا که میتوانید از انجام اینکار پرهیز کنید و فقط در مواردی که واقعاً نیازمند اینکار هستید و راه دیگری نیست، از آن استفاده کنید.
Garbage Collection
Garbage Collection نوعی مدیریت حافظهی خودکار محسوب میشود. هربار که یک شیء میسازید، object شما در heap ذخیره میشود. تا زمانیکه فضای کافی برای ذخیرهی این اشیاء داشته باشید میتوانید شیء جدید بسازید اما همانطور که میدانید حافظه نامحدود نیست و ممکن است پر شود. بنابراین باید object های بیاستفاده، از حافظه پاک شوند تا بتوان مجدداً اشیای دیگری را در حافظه ذخیره کرد. در بسیاری از زبانهای برنامهنویسی برای آزاد کردن حافظه از چیزهایی که در آن ذخیره شده، بهصورت دستی و کدنویسی باید اینکار انجام شود. مثلاً در ++C برای این منظور از delete operator استفاده میشود اما سیشارپ برای این منظور از راه حلی بهتر و سادهتر به اسم Garbage Collection استفاده میکند. Garbage Collection بدون اینکه برنامهنویس نیاز باشد کار خاصی انجام دهد بهصورت خودکار، اشیایی که در heap قرار دارند و به هیچ reference ای وصل نیستند را پاک میکنند. اینکه دقیقاً چه زمانی اینکار انجام میشود، مشخص نیست اما اگر میخواهید قبل از پاک شدن یک شیء توسط garbage collector کار خاصی را انجام دهید یا فقط از پاک شدن آن مطلع شوید از destructors استفاده میکنید. از destructor در سطوح حرفهای برنامهنویسی استفاده میشود و دانستن آن چندان برای شما که اول راه هستید ضروری نیست اما اگر در این مورد کنجکاوید میتوانید شخصاً در مورد آن تحقیق کنید.
Object Initializers
Object Initializers روشی دیگر برای ساخت شیء و مقدار دهی به field ها و property های (در مورد property بعداً بحث خواهیم کرد) کلاس است. با استفاده از object initializers، دیگر constructor کلاس را به روش معمول صدا نمیزنید بلکه اسم field ها و property ها را مینویسید و مستقیماً به آنها مقدار میدهید. استفادهی اصلی object initializers برای anonymous type های ساخته شده توسط LINQ است (در مورد LINQ و anonymous types بعداً صحبت خواهیم کرد) اما در حالت معمول نیز میتوانند مورد استفاده قرار گیرند.
به مثال زیر توجه کنید:
using System; class Human { public string Name; public int Age; public void Show() { Console.WriteLine(Name + " " + Age); } } class ObjInitializersDemo { static void Main() { Human Man = new Human { Name = "Paul", Age = 28 }; Man.Show(); } }
همانطور که میبینید، Man.Name برابر با Paul و Man.Age را برابر با ۲۸ قرار دادهایم. نکته اینجاست که از هیچ constructor ای استفاده نکردهایم بلکه شیء Man توسط خط کد زیر تولید شده است:
Human Man = new Human { Name = "Paul", Age = 28 };
Optional Arguments
C# 4.0 ویژگی جدیدی بهنام Optional Arguments دارد که باعث میشود برای فرستادن argument ها و دریافت پارامترها، روش دیگری نیز در دستتان باشد. همانطور که اسم این ویژگی جدید (argument های دلخواه) بیانکنندهی ماهیت آن است، با استفاده از optional arguments میتوانید متدهایی تعریف کنید که از بین چندین پارامترش، بعضی از آنها قابلیت این را داشته باشند که برای دریافت argument، اجباری نداشته باشند و اگر صلاح دانستید به آنها argument دهید. استفاده از این ویژگی بسیار راحت است، کافی است هنگام تعریف پارامترها به آنها یک مقدار پیشفرض بدهید.
به نمونهی زیر توجه کنید:
public void OptArg(int a, int b = 2, int c = 3) { Console.WriteLine("This is a, b, c: {0} {1} {2}", a, b, c); }
در متد بالا، پارامتر b و c اختیاری هستند و به این طریق شما ویژگی optional argument را فعال کردید. توجه کنید که پارامتر a همان حالت معمول را دارد و اختیاری نیست و حتماً باید مقدار دهی شود.
به مثال زیر توجه کنید:
using System; class OptionalArgs { public void OptArg(int a, int b = 2, int c = 3) { Console.WriteLine("This is a, b, c: {0} {1} {2}", a, b, c); } } class OptionalArgsDemo { static void Main() { OptionalArgs ob = new OptionalArgs(); ob.OptArg(5); ob.OptArg(3, 9); ob.OptArg(4, 6, 8); } }
در این مثال، متد ()OptArg به سه طریق صدا زده شده است. ابتدا یک، سپس دو و در نهایت سه argument دریافت کرده است. این امکان وجود ندارد که این متد را بدون هیچ argument ای اجرا کنید چراکه پارامتر a اختیاری نیست و مقداردهی به آن اجباری است. آیا استفاده از این روش شبیه به method overloading نیست؟ بله، شما با این کار به یک متد به سه طریق مقدار دادهاید که به method overloading شباهت دارد اما این روشها جایگزینی برای هم نیستند بلکه در بعضی موارد برای راحتی برنامهنویس استفاده میشود و در برخی موارد برای خط کد کمتر ممکن است از این روش هم بتوانید بهرهمند شوید. توجه کنید که اگر به پارامترهای دلخواه هیچ مقداری ندهید، مقدار پیشفرض آنها در نظر گرفته میشود. همچنین پارامترهای که اجباری هستند باید پیش از پارامترهای اختیاری قرار بگیرند. برای نمونه، خط کد زیر نادرست است:
public void OptArg(int b = 2, int c = 3, int a) // Error! // Or public void OptArg(int b = 2, int a, int c = 3) // Error!
بهدلیل اینکه پارامتر a اجباری است باید پیش از پارمترهای اختیاری قرار بگیرد. از optional arguments نیز میتوانید در constructor، indexer و delegate نیز استفاده کنید (indexer و delegate در مقالات آینده مورد بحث قرار میگیرند).
Named Arguments
یکی دیگر از ویژگیهای جدیدی که به C# 4.0 افزوده شده، named argument است. همانطور که میدانید، هنگامیکه argument هایی را به متد میفرستید، ترتیب این argument ها باید مطابق با ترتیب پارامترهایی باشد که در متد تعریف شدهاند. با استفاده از named arguments میتوانید این محدودیت و اجبار را بردارید. استفاده از این ویژگی نیز بسیار ساده است، کافیست نام پارامتری که argument قرار است به آن داده شود را در هنگام ارسال argument مشخص کنید و بعد از اینکار، دیگر ترتیب argument ها اهمیتی ندارد.
به مثال زیر توجه کنید:
using System; class NamedArgsDemo { static int Div(int firstParam, int secondParam) { return firstParam / secondParam; } static void Main() { int result; // Call by use of normal way (positional arguments). result = Div(10, 5); Console.WriteLine(result); // Call by use of named arguments. result = Div(firstParam: 10, secondParam: 5); Console.WriteLine(result); // Order dosn't matter with a named argument. result = Div(secondParam:5, firstParam: 10); Console.WriteLine(result); } }
همانطور که میبینید متد ()Div در هر سه باری که فراخوانی شده، نتیجهی یکسانی را تولید کرده است. ابتدا از این متد بهصورت معمول استفاده کردیم و سپس در فراخوانی بعدی، نام پارامترها را نیز مشخص کردهایم (در اینجا از ویژگی named arguments استفاده شد) و در نهایت همانطور که میبینید، ترتیب را بههم زدیم و جای argument ها را عوض کردیم اما نتیجه تغییر نکرده است.
همچنین میتوانید named arguments را با حالت معمول (positional arguments) ادغام کنید به شرطیکه همهی positional arguments را پیش از named arguments قرار دهید:
Div(10, secondParam: 5);
از named arguments و optional arguments همچنین میتوانید در constructor، indexer و delegate نیز استفاده کنید. (indexer و delegate جزء مباحث آینده هستند.)
داوود
1 March 2013
سلام مسعود جان؛ ممنون بخاطر گذاشتن این قسمت و همچنین از گذاشتن اشکال متنوع جهت درک بهتر.
رضا
1 March 2013
با سلام آقا مسعود دستتون درد نکنه بابت این آموزش خوبتون راستی درباره ی try و finally و…….. اینها رو آموزش ندادیدو آیا می دهید ببخشیید آقا مسعود گفته بودید توی آموزش قبلی توی این اموزش حل تمرین رو میزارید ولی نذاشتید اگر ممکنه آموزشها رو بزارید ب و اگر میشه تمرینها رو هم بیشتر کنید باتشکر
مسعود درویشیان
1 March 2013
سلام رضا جان، بله حتماً try-catch رو میگیم.
آره قرار بود این جلسه حل تمرین باشه ولی احساس کردم اگه یه هفتهی دیگه هم فرصت بدم تا خودتون بیشتر روی مساله فکر کنید بهتر باشه
جلسه آینده حل تمرین خواهد بود
موفق باشید
مهدی
1 March 2013
سلام؛
آره آقا مسعود؛ حق با شماست؛ برای حل تمرینها حتما دو هفته فرصت بدید. اینجوری باعث میشه که ما همیشه به لقمه آماده عادت کنیم و از خودمون هیچ تلاشی نکنیم.
مسعود درویشیان
1 March 2013
دقیقاً هم همینو میخوام :) از مغز باید واسه فکر کردن هم استفاده کرد، نه فقط واسه انبار کردن اطلاعات…
داوود
2 March 2013
سلام؛ من هم کاملا با نظر آقا مهدی موافقم، این که حل تمرین رو زود ببینیم هیچ فایده ای در یادگیری ما نداره.
آقا مسعود درس بعدی جمعه یا شنبه ست؟ میخوام ببینم آخرین مهلت تحویل برنامه چه زمانی ست؟
بازهم از شما ممنونم
رضا
2 March 2013
با سلام آقای درویشیان ازتون بابت پاسخی که به میدهید بی نهایت تشکر میکنم
ببخشیید آقای درویشیان دو تا سوال داشتم میتونید راهنماییم کنید
برنامه ای بنویسید که حقوق کارمندی رو دریافت کند و مالیات حقوق وی را براساس موارد زیر حساب کند 1- تا 150000 ریال از مالیات معاف 2- از 1500001 تا 230000 ریال 10 درصد نسبت به مبلغ مازاد ا این نسبت به مبلغ مازاد یعنی چی میتونید با مثال توضیح بدهید.
سوال دوم این هستش برنامه ای بنویسید که اسم سه نفر رو از ورودی دریا فت کند و آنها را به ترتیب حروف الفبا بنویسید.
آقا مسعود اگر بتونید از توابع اماده ی سی شارپ هم برای استرینگ ها و……… رو آموزش بدهید خیلی عالی میشه
با سپاس
داوود
3 March 2013
سلام آقا رضا؛
(با اجازه آقا مسعود)
شبتون بخیر؛ ببینید دوست عزیز ؛ وقتی که میگه مبلغ مازاد، منظورش مازاد بر مبلغی است که به اون مبلغ ؛ مالیاتی تعلق نمیگیره. در واقع در مثال شما تا سقف 150000 ریال رو هیچ مالیاتی نمیگیره، یعنی این رو گذاشتن تا در دنیای واقعی کمکی باشه برای افرادی که حقوق چندان زیادی دریافت نمی کنند.
و اما وقتی که مبلغ از این میزان بیشتر شد(که میشه گفت مبلغ 150000 ریال در اینجا در واقع یک معیار به حساب میاد) میان و به نسبت مازاد حقوقی که از معیار مشخص شده بیشتر هستش درصد میبندن، در مثال شما مازاد حقوق شخص بعدی که ما فرض میکنیم 220000 ریال هستش، این مبلغ رو از مبلغ شاخص یاهمون معیار کم می کنیم که میشه 70000 ریال؛ خب طبیعی است که 10 درصد 70000 ریال برابر با 7000 ریال هستش که همین مقدار نیز بعنوان مالیات حساب میشه و از 70000 ریال کم میشه؛ البته چون گفته از مازاد پس رو همین مقدار تاثیر گذار هستش ولی اگه میگفت از کل حقوق خب میشد 220000 ریال که ده درصد این مبلغ برابره با 22000 ریال.
امیدوارم توضیحاتم شما رو کمک کرده باشه. برنامه رو هم اگه آقای درویشیان اجازه بده تا فردا براتون رو سایت میذارم.
در خصوص برنامه دوم اگه اشتباه نکنم فکر کنم باید اسامی اشخاص رو در آرایه ریخته و سپس اول اسمها رو با همدیگه مقایسه کرده و نسبت به چاپ اون اقدام کنید.
موفق باشید.
رضا
6 March 2013
با سلام ببخشیید آقا داود اگر ممکنه برنامه اش رو بنویس برام میل کن چون بلد نیستم [email protected]
باتشکر
داوود
6 March 2013
خواهش می کنم آقا رضا؛
این برنامه اولی در خصوص محاسبه مالیات هستش؛ از آقا مسعود درخواست می کنم اگه ممکنه ایرادات احتمالی برنامه رو بگن + اگه ممکنه بگن چجوری میشه شی گرا تر بشه؟؟
ولی برای شما آقا رضا برنامه جواب میده و میتونید دریافتش کنید.
using System;
class Payment
{
static void Main()
{
Process MyProject = new Process();
MyProject.GetNum();
MyProject.Result(“information about your Payment:\n”);
Console.ReadLine();
}
}
class Process
{
public double Total;// All payment without any process(kolle hoghogh)
public double Tax;//tax(Maliat)
public double Excess;//excess than 150000 Rials(mazad bar 150000 Rials)
public double GetNum()
{
Console.Write(“please enter your Payment:”);
Total = Convert.ToDouble(Console.ReadLine());
return Total;
}
public void Result(string message)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(message);
Console.ForegroundColor = ConsoleColor.White;
if (Total <= 150000)
{
Tax = 0;
Console.WriteLine("your Net Payments is:{0} Rial(s) and Tax is:{1} Rial(s)", Total,Tax);
}
else
{
Excess = Total – 150000;
Tax=Excess*0.1 ;
Total = Total – Tax;
Console.WriteLine("your Net Payments is:{0} Rial(s) and Tax is:{1} Rial(s)", Total, Tax);
}
}
}
[/C#]
داوود
9 March 2013
اینهم برنامه بعدی شما آقا رضا؛ مرتب کردن رشته های دریافتی:
[C#]
using System;
class MyProject
{
public static string[] str = new string[3];
static void Main()
{
for (int i = 0; i < 3; i++)
{
str[i] = Console.ReadLine();
}
Array.Sort(str);
foreach (string st in str)
Console.WriteLine(st + "");
}
}
[/C#]
محمد
6 March 2013
سلام
ممنون بابت آموزش های خوبتون.
ایا سی شارپ رو در محیط Windows Formاموزش میدید؟
با تشکر
داوود
6 March 2013
سلام آقا محمد؛
(با اجازه آقا مسعود)
محمد جان جواب شما منفی است ؛ ولی اگه همین درسها رو خوب یاد بگیرید براحتی میتونید تو محیط ویژوال هم برنامه نویسی کنید. در واقع پایه و اساس کار از همینجا شروع میشه.
موفق باشید
داوود
9 March 2013
سلام مسعود جان؛
عصرتون بخیر و خسته نباشید.
مسعود جان یک سوال از خدمتتون داشتم؛ دیروز که داشتم برنامه دوستمون آقا رضا رو در خصوص مرتب کردن رشته دریافتی می نوشتم؛ قبل از اینکه با تابع از پیش تعریف شده array.sort آشنا بشم حسابی اذیت شدم و میشه گفت نصف روز باهاش ور رفتم که ببینم با چه منطقی میشه برنامه رو نوشت. راستش راههای مختلف رو امتحان کردم که ببینم چجوری میشه بدون استفاده از تابع فوق؛ خودمون روش حلشو بنویسیم. حالا یه سوال!! آیا ایراد از من بود که همون اول از تابع فوق استفاده نکردم؟؟ یا اینکه چون زمانی که ما میخوندیم (البته خوب نخوندیم) امثال زبانهایی مثل++ C و یا پاسکال فاقد این توابع بودند و در واقع به نوعی ما خودمون با اینها کلنجار می رفتیم؟؟؟ و حالا هم طبق همون عادت قدیمی راه مشکل تر رو انتخاب می کنیم؟ (مثلا هنوز بعضی ها محیط NC رو فراموش نکردن و گاها کارهای کپی و دیگر کارهاشونو با این نرم افزار تحت Dos انجام میدن).
بهرحال من خیلی با برنامه ور رفتم و در اینجا ازتون چند سوال داشتم!
1- ببینید برنامه الان اگه اسم اول از بقیه جلوتر باشه کار می کنه ولی در غیر اینصورت نه!!!
2- میشه بگید برنامه رو به چه نحوی شی گرا بنویسم که در یک متد نامها رو بگیرم و در متد دیگه کار مرتب سازی رو انجام بدم؟؟؟(میخوام مرتب سازی به نحوی باشه که اگه حروف اول یکسان بودن بتونه حروف بعدی رو هم لحاظ کنه ، مثلا اگه اسمی بود با عنوان ahmad و یکی دیگه هم amin بتونه اول ahmad رو نشون بده و نه امین رو؟؟)
3- آیا برای دریافت رشته و یا کلا متعیر متد تعریف کنیم بهتر نیست؟؟
خیلی خیلی ببخشید و عذر میخوام از طرح این همه سوال.
مسعود درویشیان
15 March 2013
خب اینکه نمیدونستید همچین تابعی هم هست و خودتون واسش تلاش کردید مشکلی نداره، خوب هم هست چون باعث شده روش فکر کنین! در مورد شیگرایی هم توی تمرینها انشالله کامل متوجه میشی. آره اگه هرکاری رو متد کنی خیلی بهتره…
در ضمن، ()Array.Sort برات موردی رو که تو گزینهی 2 نوشتی انجام میده
داوود
9 March 2013
سلام دوباره ؛ ببخشید اگه میشه از این پاراگراف به بعد رو در ادامه پست قبلی من اضافه کنید؛ فراموش کردم بذارم.
ضمنا آقا مسعود من اون مقدار کدی رو که دیروز نوشتم و نصفه و نیمه جواب گرفتم رو براتون میذارم؛ عذرمیخوام که قسمتهای کامنت رو هم میذارم؛ گفتم شاید بخواین ببینین.
[#c]
using System;
class MyProject
{
public static string[] str = new string[3];
public static char[] arr=new char[3];
public static char[] s=new char[3];
public static string[] sort = new string[3];
static void Main()
{
int FirstWrd = 0;
for (int i = 0; i < 3; i++)
{
str[i] = Console.ReadLine();
arr = str[i].ToCharArray();
s[FirstWrd] = arr[0];
FirstWrd++;
}
FirstWrd = 0;
for (int j = 0; j < 3; j++)
{
if (s[0] < s[1] && s[0] < s[2])
{
sort[j] = str[0];
}
Console.WriteLine("{0}", sort[0]);
}
}
}
class sort
{
int size = 3;
// public string[] str;
public void getname()
{
}
//public void getName(string Message)
//{
// Console.WriteLine(Message);
// for (int i = 0; i <3; i++)
// {
// str[i] = Console.ReadLine();
// }
//}
}
[/#C]
مهسا
15 March 2013
با سلام ببخشیید آقای درویشیان آموزش قسمت 28 رو کی میزارید و اگر ممکنه تا آخر عید یه کاری کنید که هر دو روز یا هر سه روز به یه جایی برسیم آموزش بدهید من باید تا آخر عید سی شارپ رو خوب یاد بگیرم چون برای پایان نامه ام لازم دارم
خواهش میکنم آموزشها رو سریعتر روی سایت قرار بدهید
محمد فر
29 March 2013
سلام و با عرض خسته نباشید.ایا شما ادامه مباحث رو میذارید.اگه جواب مثبته لطفا بگید کی شروع می کنید چون می خوام برنامه ریزی کنم.من درساتون رو خیلی دقیق خوندم واقعا عالیه.الان من درس چهاردهم هستم تازه سه روزم هست با این سایت خوب اشنا شدم.ممنون
مسعود درویشیان
29 March 2013
بله حتماً، بعد از 13 فروردین مجدداً هر هفته مقالات منتشر میشوند. موفق باشید
مهسا
5 April 2013
با سلام ببخشیید پس این آموزش قسمت 28 ام رو کی میزارید منتظریممممممممممممممممممممممممممممممممممم
الان حدود 4 هفته از آخرین انتشارتون گذشته است
باتشکر
مسعود درویشیان
5 April 2013
سلام
امشب یا نهایتا فردا قسمت 28 پخش میشه
محمد فر
12 April 2013
سلام استاد.
چرا کم پیدا شدید؟
یه سئوال داشتم ado.net اخرین ورژنش چیه؟
مسعود درویشیان
12 April 2013
http://msdn.microsoft.com/en-us/library/ex6y04yf.aspx
محمد فر
13 April 2013
ممنون.از اینکه جواب دادید.
محمد فر
13 April 2013
سلام.
یک مطلبی راجب تغییرها در سی شارپ توی ذهنم است ولی دقیقا یادم نیست.اینکه وقتی یک value type را اعلان می کنیم مقدار اولیه ان صفر است؟
و اینکه یه جاهای value type ها از هیپ فضا می گیرند.این مواقع کی هست؟
در مورد ref type ها چطور ایا میشه اونها از stak فضا بگیرند.منظورم این روشی که شما در این مقاله گفتید نیست. boxing & unboxing
Mersad
30 August 2013
سلام آقای درویشیان
کد زیر رو در نظر بگیرید
چرا وقتی متد print رو به صورت زیر فراخوانی میکنم، خطا میده؟
کلا در فراخوانی متدهایی که چندتا پارامتر اجباری و اختیاری دارن، به چه صورت میشه به صورت بالا، مثلا پارامترهای اختیاری ای که در وسط قرار گرفتن رو مقدار دهی نکنیم و پارمترهای ابتدایی و انتهایی رو مقدار دهی کنیم؟
مسعود درویشیان
5 October 2013
از وسط نمیشه جای optional argument رو خالی گذاشت! اگه نمیخواهید تغییر کنه، باید همون پارامتر “Behdad” رو بهش بدید.
اسماعیل
23 April 2014
سلام اگه ممکنه برنامه دریافت ده عدد و نمایش بزرگترین مقدار را به صورت بازگشتی برام ایمیل کنید
باتشکر
a-p
6 August 2014
بسم الله الرحمن الرحیم
سلام
می شود boxوunboxingرا از روی برنامه دقیقتر برایم توضیح دهید
تبدیل value typeبهrefrence typeوبرعکس را متوجه نمی شوم
بهنام
11 August 2014
سلام اقای درویشیان واقعا من توی ایران انسان هایی مثل شما رو کم دیدم
شما بدون هیچ گونه تبلیغاتی مطالب بی نظیری را برای آموزش قرار داده اید که از نظر سطح کیفیت اموزش با سایت های بزرگ خارجی رقابت می کند
و همینطور بابت این اموزش ها هیچ سودی نصیبتان نمی شود
امیدوارم افرادی مثل شما در ایران بازم پیدا شه
sara
6 September 2014
مرسی عالی بود
فرزاد کریمی منظور
1 February 2017
با سلام و خسته نباشید
چرا در موضوع boxing and unboxing در شکل مقدار i برابر 1 شده ولی در عکس مقدارش برابر 4 هست این موضوع رو درک نمی کنم.