PDA

نسخه کامل مشاهده نسخه کامل : آموزش جامع و كامل برنامه هاي كاربردي



WooKMaN
20-11-2005, 08:43
سلام دوستان
از اين به بعد قراره تو اين انجمن شاهده بزرگترين انجمن در مورد آموزش برنامه هاي كاربردي باشيد
اميدوارم بتونم رضايت خاطر شمارو جلب كنم
:happy:

فهرست:

1- تاپيك 2 تا 8 آموزش Asp (اي اس پي)
2- تاپيك 9 آموزش SQL (اس كيو ال)
3- تاپيك 10 تا 12 آموزش JavaScript (جاوا اسكريپت)
4- تاپيك 13 تا 32 آموزش C# (سي شارپ)
5- تاپيك 33 معرفي اوليه VB.NET
6- تاپيك 34 مقايسه ADO و ADO.Net
7- تاپيك 35 تا 38 آموزش Pascal (پاسكال)

WooKMaN
20-11-2005, 08:46
آموزش ASP از مقدماتي تا پيشرفته



يك فايل ASP مى تواند حاوى متون، Tagهاى HTML و اسكريپت ها باشد. اسكريپت ها در يك فايل ASP بر روى سرور اجرا مى شوند.

--------------------------------------------------------------------------------
به عنوان پيش نياز چه چيزى را بايد بدانيد؟

قبل از شروع، بايد با مسائل زير را تا حدودى آشنا باشيد:


WWW و HTML و مسائل اوليه ساخت صفحات Web
يك زبان اسكريپت نويسى همچون JavaScript يا VBScript

--------------------------------------------------------------------------------
ASP چيست؟
ASP حروف اختصارى Active Server Pages است.
ASP برنامه اى است كه درون IIS اجرا مى شود.
IIS حروف اختصارى Internet Information Services است.
IIS به عنوان يك مولفه رايگان با ويندوز 2000 عرضه مى شود.
IIS همچنين به عنوان جزئى از Windows NT 4.0 Option Pack است.
Option Pack مى تواند از سايت مايكروسافت داون لود شود.
PWS نسخه كوچكتر - ولى كاملا عمل كننده - از IIS است.
PWS را مى توانيد در سى دى ويندوز 95 يا 98 خود پيدا كنيد.
سازگارى ASP


ASP تكنولوژى مايكروسافت است.
براى اجراى IIS بايد ويندوز NT نسخه 4.0 يا بالاتر را داشته باشيد.
براى اجراى PWS بايد ويندوز 95 يا بالاتر را داشته باشيد.
ChiliASP تكنولوژى است كه ASP را بدون نياز سيستم عامل ويندوز اجرا مى كند.
InstantASP تكنولوژى ديگرى است كه ASP را بدون نياز به سيستم عامل ويندوز اجرا مى كند.
يك فايل ASP چيست؟
يك فايل ASP تقريبا شبيه به يك فايل HTML است.
يك فايل ASP مى تواند حاوى متن، XML، HTML، و اسكريپت باشد.
اسكريپت هاى درون يك فايل ASP بر روى Server اجرا مى شود.
يك فايل ASP پسوند "asp." دارد.
فرق ASP با HTML چيست؟
وقتى كه Browser (كاوشگر اينترنت) درخواست يك فايل HTML را بكند، Server آن فايل را بر مى گرداند.
وقتى كه Browser درخواست يك فايل ASP را بكند، IIS درخواست مربوطه را به موتور (هسته‌اى كه وظيفه اصلى را بازى مى كند) ASP ارجاع مى دهد. موتور ASP فايل ASP را خط به خط مى خواند، و اسكريپت هاى درون فايل را اجرا مى كند. در نهايت فايل ASP به عنوان يك فايل HTML ساده به Browser برگردانده مى شود.

--------------------------------------------------------------------------------
ASP چه كارى مى تواند براى شما انجام دهد؟
به طور ديناميكى محتويات يك Web page را ويرايش يا اضافه كند.
به درخواست هاى كاربر كه از فرم هاى HTML ارسال شده اند پاسخ دهد.
به هر گونه اطلاعات با بانك اطلاعاتى دسترسى پيدا كرده و نتايج را به Browser برگرداند.
سفارشى نمودن (Customize) يك Web page تا براى كاربران مختلف مفيدتر باشد.
مزاياى استفاده از ASP به جاى CGI و Perl سرعت و سادگى است.
فراهم كردن امنيت بيشتر به گونه اى كه كد ASP شما از طريق Browser قابل مشاهده نيست.
از آن جايى كه فايلهاى ASP به شكل HTML برگردانده مى شوند، ميتوانند بوسيله هر Browserى مشاهده گردند.
برنامه نويسى درست ASP مى تواند ترافيك شبكه را به حداقل برساند.

WooKMaN
20-11-2005, 08:48
ادامه بحث ASP

شما مي توانيد ASP را بدون نياز به يک سرور خارجي اجرا کنيد. براي انجام اين کار شما بايد Microsoft's Personal Web Server (PWS) يا (Internet Information Server (IIS را در رايانه خود نصب کنيد.

--------------------------------------------------------------------------------
چگونه ASP را در رايانه خود اجرا کنيد؟

شما مي توانيد ASP را بدون سرور خارجي در رايانه شخصي خود اجرا کنيد. براي انجام اين کار بايد Microsoft's (Personal Web Server (PWS يا (Internet Information Server (IIS را در رايانه خود نصب کنيد.
اگر در مورد اجراي ASP جدي هستيد، بايد حداقل ويندوز 98، نسخه دوم (Second Edition) داشته باشيد.
اگر در مورد اجراي ASP بسيار جدي هستيد، بايد از ويندوز 2000 استفاده کنيد.
--------------------------------------------------------------------------------
چگونه PWS را در ويندوز 95 نصب کنيد و ASP اجرا کنيد؟

(Personal Web Server (PWS همراه ويندوز 95 نيست!!

براي اجراي ASP بر روي ويندوز 95، شما بايد "Windows NT 4.0 Option Pack" را از مايکروسافت داون لود کنيد.

داون لود "Windows NT 4.0 Option Pack"


--------------------------------------------------------------------------------
چگونه PWS را در ويندوز NT نصب کنيد و ASP اجرا کنيد؟

(Personal Web Server (PWS همراه ويندوز NT نيست!!

براي اجراي ASP بر روي ويندوز 95، شما بايد "Windows NT 4.0 Option Pack" را از مايکروسافت داون لود کنيد.

داون لود "Windows NT 4.0 Option Pack"


--------------------------------------------------------------------------------
چگونه PWS را در ويندوز 98 نصب کنيد و ASP اجرا کنيد؟


شاخه Add-ons را در سي دي ويندوز 98 خود باز کنيد، شاخه PWS را پيدا کرده و فايل setup.exe را اجرا کنيد.
يک شاخه Inetpub در هارد شما ايجاد خواهد شد. آن را باز کنيد و شاخه [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] را پيدا کنيد.
يک شاخه جديد درست کنيد و نام آن را چيزي شبيه به "MyWeb" بگذاريد.
از يک ويرايشگر متن استفاده کنيد و کدهاي ASPي را بنويسيد، فايل را به نام "test1.asp" را در شاخه "MyWeb" ضبط کنيد.
مطمئن شويد که وب سرور شما اجرا است - برنامه نصب يک آيکن جديد در Task Bar شما اضافه کرده است (اين نشانه PWS است). بر روي آن کليک کنيد و دکمه Start را در پنجره اي که آمده بزنيد.
Browser خود را باز کنيد و تايپ کنيد "[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]"، تا اولين صفحه ASP خود را ببينيد.
چگونه PWS را در ويندوز Me نصب کنيد و ASP اجرا کنيد؟

(Personal Web Server (PWS در ويندوز Me وجود ندارد !!

مقاله مربوطه را در سايت مايکروسافت بخوانيد


--------------------------------------------------------------------------------
چگونه IIS را در ويندوز 2000 نصب کنيد و ASP اجرا کنيد؟


از دکمه Start به Settings و سپس Control Panel برويد.
در پنجره Control Panel آيکن Add/Remove Programs را انتخاب کنيد.
در پنجره Add/Remove Programs گزينه Add/Removes Windows Components را انتخاب کنيد.
در پنجره جديد گزينه Internet Information Services را انتخاب کرده، OK را بزنيد.
يک شاخه Inetpub در هارد شما ايجاد خواهد شد. آن را باز کنيد و شاخه [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] را پيدا کنيد.
يک شاخه جديد درست کنيد و نام آن را چيزي شبيه به "MyWeb" بگذاريد.
از يک ويرايشگر متن استفاده کنيد و کدهاي ASPي را بنويسيد، فايل را به نام "test1.asp" را در شاخه "MyWeb" ضبط کنيد.
مطمئن شويد که وب سرور شما اجرا است - برنامه نصب يک آيکن جديد در Task Bar شما اضافه کرده است (اين نشانه IIS است). بر روي آن کليک کنيد و دکمه Start را در پنجره اي که آمده بزنيد.
Browser خود را باز کنيد و تايپ کنيد "[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]"، تا اولين صفحه ASP خود را ببينيد.

--------------------------------------------------------------------------------
چگونه IIS را در ويندوز XP نصب کنيد و ASP اجرا کنيد؟

نکته: شما نمي توانيد ASP را روي ويندوز XP نسخه خانگي (Home Edition) اجرا کنيد.
از دکمه Start به Settings و سپس Control Panel برويد.
در پنجره Control Panel آيکن Add/Remove Programs را انتخاب کنيد.
در پنجره Add/Remove Programs گزينه Add/Removes Windows Components را انتخاب کنيد.
در پنجره جديد گزينه Internet Information Services را انتخاب کرده، OK را بزنيد.
يک شاخه Inetpub در هارد شما ايجاد خواهد شد. آن را باز کنيد و شاخه [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] را پيدا کنيد.
يک شاخه جديد درست کنيد و نام آن را چيزي شبيه به "MyWeb" بگذاريد.
از يک ويرايشگر متن استفاده کنيد و کدهاي ASPي را بنويسيد، فايل را به نام "test1.asp" را در شاخه "MyWeb" ضبط کنيد.
مطمئن شويد که وب سرور شما اجرا است - برنامه نصب يک آيکن جديد در Task Bar شما اضافه کرده است (اين نشانه IIS است). بر روي آن کليک کنيد و دکمه Start را در پنجره اي که آمده بزنيد.
Browser خود را باز کنيد و تايپ کنيد "[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]"، تا اولين صفحه ASP خود را ببينيد.

WooKMaN
20-11-2005, 08:49
ادامه بحث ASP

شما نمي توانيد سورس کد هاي ASP را بوسيله انتخاب گزينه View Source در Browser مشاهده کنيد، شما فقط خروجي فايل ASP را مشاهده مى‌کنيد که HTML ساده است. زيرا که اسکريپت ها قبل از اين که نتايج به Browser فرستاده شود بر روي سرور اجرا مى‌گردد.

در خودآموزهاي ASP ما تمامي مثالها علاوه بر نتيجه نهايي حاوي سورس کد مربوطه هستند. اين مسئله امکان فهميدن اينکه مثالها چگونه کار مي کنند را براي شما ساده مي کند.
--------------------------------------------------------------------------------
مثالها

نوشتن متن با ASP
چگونه با کمک گرفتن از ASP متوني را بنويسيم.

اضافه کردن HTML به متون
چگونه متون را با استفاده از Tagهاي HTML فرمت بندي کنيم؟


--------------------------------------------------------------------------------
قواعد اساسي نحو
يک فايل ASP به طور عادي دقيقا همانند HTML حاوي Tagهاي HTML است. اگر چه، يک فايل ASP مي تواند همچنين حاوي Scriptها نيز باشد. اين اسکريپت ها به وسيله علامت هاي %> و <% احاطه شده اند. اسکريپت هاي سرور بر روي سرور اجرا مي شود و مي تواند حاوي هر گونه expressions، دستورات (Statements)، توابع، يا عملگرهايي باشد.


--------------------------------------------------------------------------------
آبجکت Response
متد Write مربوط به آبجکت Response براي فرستادن محتويات به Browser استفاده مي شود. به عنوان مثال، دستورات زير براي فرستادن متن "سلام دنيا!" به Browser استفاده مى‌شود.
<%
response.write("سلام دنيا!")
%>



--------------------------------------------------------------------------------
VBScript
اين امکان وجود دارد که از که از زبان هاي مختلف اسکريپت نويسي در فايلهاي ASP استفاده کنيد. اگرچه زبان پيش فرض، VBScript است.
<html>
<body>
<%
response.write("سلام دنيا!") %>
</body>
</html>

مثال بالا "سلام دنيا!" را در قسمت body متن مي نويسد.

--------------------------------------------------------------------------------
JavaScript
براي اين که JavaScript را به عنوان زبان پيش فرض براي يک صفحه خاص مشخص کنيد مي بايست از راهنماهاي زباني در ابتداي صفحه خود استفاده کنيد:
<%@ language="javascript"%>
<html>
<body>
<%
Response.Write("Hello World!")
%>
</body>
</html>

نکته: JavaScript برعکس VBScript به بزرگ يا کوچک بودن حروف حساس است. شما مجبور خواهيد بود که وقتي زبان احتياج دارد، کد ASP خود را با حروف بزرگ يا کوچک بنويسيد.

--------------------------------------------------------------------------------
ساير زبان هاي اسکريپ نويسي
ASP همراه با VBScript و JScript (پياده سازي مايکروسافت از JavaScript) عرضه مي شود. اگر شما مي خواهيد که با زبان ديگري همچون PERL - REXX يا Phyton کد بنويسيد، مجبور خواهيد بود که موتور Script مربوط به آنها را نصب کنيد.
مهم: به خاطر اين که اسکريپت ها بر روي سرور اجرا مي شوند، به هيچ وجه لازم نيست Browserي که فايل ASP را نشان مي دهد از Scripting پشتيباني کند!

WooKMaN
20-11-2005, 08:50
ادامه بحث ASP

يک متغيير براي نگهداري اطلاعات استفاده مي شود.

اگر يک متغيير بيرون از يک رويه (procedure) تعريف شود، ميتواند بوسيله هر اسکريپت موجود در فايل ASP تغيير يابد. اگر متغيير داخل يک رويه تعريف شود، آن هر بار که رويه اجرا مي شود، ايجاد و سپس نابود مي شود.
--------------------------------------------------------------------------------
مثالها

تعريف کردن يک متغيير
متغييرها براي نگهداري اطلاعات استفاده مي شود. اين مثال نشان مي دهد که چگونه يک متغيير تعريف کنيم، چگونه يک مقدار به آن بدهيم، و چگونه از آن مقدار در يک نوشته استفاده کنيم.

تعريف يک آرايه
آرايه‌ها براي ضبط يک سري از اطلاعات مرتبط به هم استفاده مي شوند. اين مثال نشان مي دهد که چگونه آرايه‌اي تعريف کنيم که حاوي نام هايي باشد.

چرخشي بر روي Headerهاي HTML
اين مثال نشان مي دهد که چگونه روي شش Header يا تيتر موجود در HTML گردش کنيم؟

نشان دادن پيغام خوش‌آمدگويي بر حسب زمان با استفاده از VBScript
اين مثال بر حسب زمان سرور يک پيغام مختلف به کاربر نشان خواهد داد.

نشان دادن پيغام خوش‌آمدگويي بر حسب زمان با استفاده از JavaScript


--------------------------------------------------------------------------------
عمر متغييرها
متغييري که خارج از يک رويه (procedure) تعريف شده است مي تواند بوسيله هر اسکريپتي در فايل ASP در دسترس قرار گرفته و تغيير کند.

متغييري که در داخل يک تابع تعريف شده است هر بار که رويه اجرا مي شود درست و نابود مي شود. هيچ اسکريپتي بيرون از رويه نمي تواند به آن متغيير دسترسي داشته باشد يا آن را تغيير دهد.

براي تعريف متغييرهايي که براي بيش از يک فايل ASP قابل دسترس باشند، آنها را به عنوان متغييرهاي Session يا متغييرهاي Application تعريف کنيد.

متغييرهاي Session
متغييرهاي Session براي نگهداري اطلاعات راجع به يک کاربر استفاده مي شود؛ اين اطلاعات در همه صفحات يک Application قابل دسترسي خواهد بود. به طور مشخص اطلاعات نگهداري شده در Sessionها نام، شناسه و اولويت است.

متغييرهاي Application
متغييرهاي Application نيز در تمامي صفحات يک Application قابل دسترس هستند. متغييرهاي Application براي نگهداري اطالعات راجع به همه کاربران در يک Application خاص استفاده مي شود.

WooKMaN
20-11-2005, 08:51
ادامه بحث ASP

يك Cookie اغلب براى شناسائى كاربر استفاده مى‌شود.
--------------------------------------------------------------------------------

مثالها
Cookie خوش‌آمدگويى
چگونه يك Cookie خوش‌آمدگويى درست كنيم.

يك Cookie چيست؟
يك Cookie اغلب براى شناسندن كاربر استفاده مى‌شود. يك Cookie يك فايل كوچك است كه سرور آن را در كامپيوتر كاربر جاسازى مى‌كند. هر بار كه همان كامپيوتر يك صفحه را درخواست مى‌كند، Cookie نيز فرستاده مى‌شود. با ASP شما مى‌توانيد هم مقادير Cookie را بسازيد و هم آنها را استخراج نماييد.
چگونه يك Cookie بسازيد؟
Response.Cookie براى ساختن Cookie استفاده مى‌شود.

توجه: Response.Cookie بايد قبل از تگ درج شود.

در مثال زير، ما يك Cookie درست خواهيد كردم و اسم آن را "firstname" مى‌گذاريم و مقدار "Alex" را به آن مى‌دهيم:

همچنين امكان دارد كه خصوصياتى را مثل تاريخ انقضاى cookie را به آن بدهيد:


چگونه مقدار cookieها را استخراج كنيم
دستور "Request.Cookies" براى استخراج اطلاعات از cookieها استفاده مى‌شود.

در مثال زير، ما مقدار cookieى با نام "firstname" را استخراج كرده و در صفحه نشان داديم:


خروجى:


Firstname=Alex


يك Cookie با كليد
اگر يك cookie حاوى مجموعه‌اى از مقادير باشد، مى‌گوييم آن cookie دارى كليدهايى است.

در مثال زير، ما يك مجموعه cookie با نام "user" درست مى‌كنيم. cookie به نام "user" داراى كليدهايى است كه حاوى اطلاعاتى راجع به كاربر است.


<%
Response.Cookies("user")("firstname")="John"
Response.Cookies("user")("lastname")="Smith"
Response.Cookies("user")("country")="Norway"
Response.Cookies("user")("age")="25"
%>



خواندن همه Cookieها
به كد زير نگاه كنيد:

<%
Response.Cookies("firstname")="Alex"
Response.Cookies("user")("firstname")="John"
Response.Cookies("user")("lastname")="Smith"
Response.Cookies("user")("country")="Norway"
Response.Cookies("user")("age")="25"
%>


فرض كنيم كه سرور شما همه cookieهاى بالا را به كاربر فرستاده است.

حالا ما مى‌خواهيم تمام cookieها را كه به كاربر فرستاده شده است را بخوانيم. مثال زير نشان مى‌دهد كه چگونه اين كار را انجام دهيم (توجه داشته باشيد كه در مثال پايين با استفاده از HasKeys چك مى‌كند كه آيا cookie كليد دارد يا نه؟

<html>
<body>
<%
dim x,y
for each x in Request.Cookies
response.write("<p>")
if Request.Cookies(x).HasKeys then
for each y in Request.Cookies(x)
response.write(x & ":" & y & "=" & Request.Cookies(x)(y))
response.write("<br />")
next
else
Response.Write(x & "=" & Request.Cookies(x) & "<br />")
end if
response.write "</p>"
next
%>
</body>
</html>


خروجى:
firstname=Alex user:firstname=John user:lastname=Smith user: country=Norway user: age=25

اگر Browser داراى پشتيبانى Cookie نباشد چه اتفاقي مى‌افتد؟

اگر برنامه شما با Browserى سر و كار داشته باشد كه cookie را پشتيبانى نمى‌كند، بايد از روش‌هاى ديگرى براى انتقال اطلاعات از يك صفحه به صفحات ديگر در برنامه خود استفاده كنيد. دو راه براى انجام اين كار هست:

1. اضافه كردن پارامترها به URL

شما مى‌توانيد پارامترها را به URL اضافه كنيد:


<a href="welcome.asp?fname=John&lname=Smith">
Go to Welcome Page</a>



و مقادير موجود در "welcome.asp" را همچون مثال زير استخراج كنيد:

2. استفاده از form
شما مى‌توانيد از فرم‌ها استفاده كنيد. وقتى كه كاربر روى دكمه Submit كليك كند فرم ورودى‌هاى كاربر را به "welcome.asp" رد مى‌كند:

<form method="post" action="welcome.asp">
First Name: <input type="text" name="fname" value="">
Last Name: <input type="text" name="lname" value="">
<input type="submit" value="Submit">
</form>



مقادير موجود در "welcome.asp" را همچون اين مثال استخراج كنيد:


<%
fname=Request.form("fname")
lname=Request.form("lname")
response.write("<p>Hello " & fname & " " & lname & "!</p>")
response.write("<p>Welcome to my Web site!</p>")
%>

WooKMaN
20-11-2005, 08:51
ادامه بحث Asp

دستورات Request.QueryString و Request.Form مى‌توانند براى گرفتن اطلاعات از فرم‌ها، مثل ورودى‌هاى كاربر استفاده گردند.

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

مثالها
يك فرم با متد "get"
چگونه با استفاده از دستور Request.QueryString به كاربر عكس‌العمل نشان دهيد.

يك فرم با متد "post"
چگونه با استفاده از دستور Request.Form به كاربر عكس‌العمل نشان دهيد.

يك فرم با Radio Buttonها
چگونه با استفاده از دستور Request.Form و از طريق Radio Buttonها به كاربر عكس‌العمل نشان دهيد.


ورودى كاربر
آبجكت Request مى‌تواند براى گرفتن اطلاعات از كاربر از فرم‌ها استفاده گردد.


<form method="get" action="simpleform.asp">
First Name: <input type="text" name="fname">
<br />
Last Name: <input type="text" name="lname">
<br /><br />
<input type="submit" value="Submit">
</form>



ورودى‌هاى كاربر مى‌توانند از دو طريق استفاده گردد: با Request.QueryString يا Request.Form



Request.QueryString
دستور Request.QueryString براى جمع كردن مقادير موجود در يك فرم با متد "get" استفاده مي شود. اطلاعات فرستاده شده از فرمى با متد "get" براي هر كسى قابل مشاده است (اين اطلاعات در قسمت آدرس Browser نشان داده مي شود) و در مورد مقدار اطلاعات محدوديت دارد.

اگر كاربر در فرمى با متد "get" مقدار "Bill" و "Gates" را وارد كنيد، URLى كه به سرور فرستاده مى‌شود شبيه به اين خواهد بود:

[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

فرض كنيد فايل "simpleform.asp" حاوى اسكريپت زير است:


<body>
Welcome
<%
response.write(request.querystring("fname"))
response.write(" " & request.querystring("lname"))
%>
</body>


Browser خط زير در قسمت Body سند نشان خواهد داد:


Welcome Bill Gates

Request.Form


دستور Request.Form براي جمع كردن اطلاعات از يك فرم با متد "post" استفاده مى‌شود. اطلاعات فرستاده شده از فرمى با متد POST براي بقيه غيرقابل مشاهده است و هيچ محدوديتى در مقدار اطلاعات فرستاده شده ندارد.

اگر كاربر در فرمى با متد "post" كلمه "Bill" و "Gates" را تايپ كند، URLى كه به سرور فرستاده مى‌شود شبيه به اين خواهد بود:


[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

فرض كنيد كه فايل "simpleform.asp" حاوى اسكريپت زير باشد:


<body>
Welcome
<%
response.write(request.form("fname"))
response.write(" " & request.form("lname"))
%>
</body>



Browser خط زير در قسمت Body سند نشان خواهد داد:


Welcome Bill Gates


تصديق فرم يا تست معتبر بودن (درست بودن) مقادير ورودى
ورودى كاربر بايد در Browser در هر جايى كه امكان داشت (با استفاده از اسكريپتهاى client) تصديق گردد. تصديق Browserى سريعتر است و زمان load شدن سرور را نيز كاهش مى‌دهد

در صورتى كه مقادير ورودى كاربر وارد Database مى‌شود لازم است كه معتبرسازى يا تصديق ورودى‌هاى كاربر بر روى سرور انجام شود. يك راه خوب براى تصديق ورودى‌هاى كاربر، به جاى فرستادن اطلاعات به يك صفحه ديگر، پست كردن آنها به خود فايل است. در آن صورت كاربر مى‌تواند خطاها را در خود صفحه‌اى كه فرم در آن قرار دارد مشاهده نمايد. اين پيدا كردن خطا را براى وى ساده‌تر مى‌كند.

WooKMaN
20-11-2005, 08:52
ادامه بحث ASP

در ASP شما مى‌توانيد يك تابع JavaScript را از يك VBScript و برعكس صدا كنيد (اجرا كنيد)

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

مثالها
اجرا كردن يك رويه با استفاده از VBScript
چگونه يك رويه VBScript را از ASP صدا كنيم.

اجرا كردن يك رويه با استفاده از JavaScript
چگونه يك رويه JavaScript را ASP صدا كنيم.

اجرا كردن رويه‌ها با استفاده از VBScript
چگونه هر دوى رويه‌هاى JavaScript و VBScript را از داخل ASP اجرا كنيم.

رويه‌ها
سورس يك ASP مي تواند حاوي رويه‌ها و توابع باشد.

<html>
<head>
<%
sub vbproc(num1,num2)
response.write(num1*num2)
end sub
%>
</head>
<body>
<p>Result: <%call vbproc(3,4)%></p>
</body>
</html>



خط را بالاى خط قرار دهيد تا رويه‌ها و توابع را با استفاده از يك زبان ديگر scriptنويسى بنويسيد:


<%@ language="javascript" %>
<html>
<head>
<%
function jsproc(num1,num2)
{
Response.Write(num1*num2)
}
%>
</head>
<body>
<p>Result: <%jsproc(3,4)%></p>
</body>
</html>



تفاوت‌هاى بين VBScript و JavaScript
وقتى كه قصد داريد يك رويه نوشته شده در VBScript يا JavaScript را در يك فايل ASP كه با استفاده از VBScript نوشته شده، اجرا كنيد مى‌توانيد از كلمه كليدى "call" كه بعد از آن اسم رويه آماده است استفاده كنيد. اگر يك رويه احتياج به پارامترهايى داشته باشد ليست پارامترهاى بايد در بين دو پرانتز قرار بگيرد. اگر "call" را حذف كنيد، ليست پارامترها نبايد در بين دو پرانتز قرار بگيرد. اگر رويه هيچ پارامترى ندارد، استفاده از پرانتز به شما بستگى دارد و انتخابى است.

اگر قصد داريد يك رويه JavaScript يا VBScript را از يك فايل ASP كه با استفاده از JavaScript نوشته شده اجرا كنيد، هميشه بايد پس از نام رويه از پرانتز استفاده كنيد.

WooKMaN
20-11-2005, 08:55
آموزش قدم به قدم و كامل SQL


زبان SQL تنها زبان استاندارد و جامع پياده‌سازي، مديريت، نگهداري و كار با بانكهاي اطلاعاتي مي‌باشد كه تقريباً توسط تمام بانكهاي اطلاعاتي كوچك و بزرگ مانند Access، SQL Server، Oracle و DB2 پشتيباني مي‌شود. طراحان و افرادي كه بنوعي با بانكهاي اطلاعاتي سروكار دارند و همچنين برنامه نويساني كه از اين بانكها استفاده مي‌كنند هركدام بايد تا اندازه‌‌اي با اين زبان آشنايي داشته باشند. اين مقاله كه در سه قسمت تهيه شده است مي‌كوشد تا مفاهيم زبان SQL را در قالب يك مثال كاربردي بيان كند. هرچند كه مفاهيم بكار رفته در اين مقاله در تمامي بانكهاي اطلاعاتي قابل پياده‌سازي مي‌باشند ولي مثالهاي ارائه شده در 2000 SQL Server مورد تست قرار گرفته‌اند.

بانك اطلاعاتي كه در اين مقاله بعنوان مثال مورد استفاده قرار گرفته است بانك اطلاعاتي يك آموزشگاه مي‌باشد كه شامل دو جدول بنامهاي teachers و students مي‌باشد. جدول اول اطلاعات اساتيد و جدول دوم اطلاعات دانشجويان را در خود نگه مي‌دارد. جدول اول داراي چهار فيلد زير مي‌باشد: name يا نام از نوع text، family يا فاميل از نوع text، age يا سن از نوع عدد، salary يا حقوق از نوع عدد.

جدول دانشجويان نيز شامل چهار فيلد مي‌باشد، سه فيلد اول آن مشابه سه فيلد اول جدول اساتيد مي‌باشد و فيلد چهارم آن عبارتست از GPA يا معدل كه يك فيلد عددي است.

زبان SQL داراي دستورات متنوع و نسبتاً زيادي مي‌باشد. به اين دستورات Clause نيز گفته مي‌شود. در اين مقاله و قسمتهاي بعدي آن تعدادي از مهمترين Clauseهاي زبان SQL مورد بررسي قرار مي‌گيرند.

1 – دستورهاي SELECT و FROM :

هدف نهايي از دادن انبوه اطلاعات به كامپيوتر، جستجو و يافتن اطلاعات مفيد مي‌باشد. به اين عمل يعني جستجوي اطلاعات در بانك اطلاعاتي Query نيز گفته مي‌شود. اكثر دستورات زبان SQL نيز در همين راستا مورد استفاده قرار مي‌گيرند. در اين بين مهمترين و پركاربردترين دستور را مي‌توان دستور SELECT قلمداد كرد.

اين دستور جهت انتخاب يك يا چند فيلد از يك يا چند جدول مختلف مورد استفاده قرار مي‌گيرد، فيلدهاي انتخاب شده پس از اجراي query روي صفحه نمايش داده خواهند شد.

بعنوان مثال اگر در بانك اطلاعاتي فرضي خودمان بخواهيم اسم و فاميل تمام دانشجويان را مشاهده كنيم بايد برنامه‌اي به شكل زير بنويسيم:

SELECT name, family
FROM students

در اين برنامه كه به زبان SQL استاندارد نوشته شده است از دو دستور SELECT و FROM استفاده شده است. دستور SELECT مشخص مي‌كند كه چه فيلدهايي از جدول بايد نمايش داده شوند و دستور FROM نيز مشخص كننده جدولي است كه قرار است اطلاعات از داخل آن استخراج شوند. حال اگر بخواهيم نام و فاميل تمام اساتيد را ببينيم برنامه بالا را بايد بصورت زير تغيير دهيم:

SELECT name, family
FROM teachers

همان طوري كه از مثال‌هاي بالا نيز مشخص است جلوي دستور SELECT نام فيلدهايي نوشته مي‌شوند كه قرار است نمايش داده شوند و بعنوان جداكننده نيز بايد از كاراكتر كاما استفاده كرد. در صورتي كه بخواهيم تمام فيلدهاي يك جدول را ببينيم مي‌توانيم بجاي نوشتن اسم تمام فيلدها فقط از يك كاراكتر ستاره استفاده كنيم. كاراكتر ستاره بمعني تمام فيلدهاي يك جدول مي‌باشد. مثلاً دو دستور زير با هم معادلند:

SELECT *
SELECT name, family, age, gpa

2 – دستور WHERE :

دستور SELECT همان طوري كه گفته شد جهت انتخاب و نمايش تعدادي از فيلدهاي جداول مورد استفاده قرار مي‌گيرد. در اين حالت تمام ركوردها نمايش داده خواهند شد، ولي در بيشتر موارد هدف از نوشتن Query نمايش ركوردهايي است كه داراي شرايط ويژه‌اي مي‌‌باشند مثلاً نمايش مشخصات اساتيدي كه بيش از پنجاه سال سن دارند. دستور WHERE براي گذاشتن يك يا چند شرط به دستور SELECT مورد استفاده قرار مي‌گيرد. با اضافه كردن شرط به دستور SELECT تعداد ركوردهاي خروجي (پاسخ) معمولاً محدودتر مي‌شود. بعنوان مثال اگر بخواهيم مشخصات اساتيدي كه بيش از چهل سال سن دارند را ببينيم بايد برنامه‌اي بصورت زير بنويسيم:

SELECT *
FROM teachers
WHERE age > 40

در اين برنامه شرط age > 40 با استفاده از دستور WHERE به Query اضافه شده و باعث شده است تا فقط مشخصات اساتيدي نمايش داده شوند كه در اين شرط صدق مي‌كنند يعني بيش از چهل سال سن دارند.

حال اگر بخواهيم مشخصات دانشجوياني را كه نام آنها علي مي‌باشد و سن آنها نيز كمتر از پانزده سال است را ببينيم بايد Query زير را اجرا كنيم:

SELECT *
FROM students
WHERE age < 15 AND name = 'ali'

در مثال بالا دو مطلب جديد وجود دارد نخست آنكه در زبان SQL رشته متني را بايد داخل كوتيشن (‘) قرارداد. بنابراين براي معرفي كلمه‌اي بنام علي بايد آنرا بصورت ‘ali’ نوشت، زيرا در اين حالت اين كلمه يك ثابت رشته‌اي (متني) بحساب مي‌آيد. نكته ديگر آنكه مي‌توان شرطهاي مختلف را توسط AND، OR و NOT با همديگر ادغام كرده و شرطهاي پيچيده‌تري را بدست آورد. AND، OR و NOT هر سه از كلمات كليدي زبان SQL مي‌باشند. بعنوان يك مثال ديگر فرض كنيد مي‌خواهيم مشخصات تمام دانشجوياني را كه نام آنها، علي يا رضا نباشند را پيدا كنيم، برنامه‌اي كه اين Query را انجام مي‌دهد بصورت زير مي‌باشد:

SELECT *
FROM students
WHERE name NOT IN ('ali', 'reza')

در صورتي كه NOT را از برنامه بالا حذف كنيم مشخصات تمام دانشجوياني كه نام آنها علي يا رضا مي‌باشند نمايش داده خواهد شد.

در اين برنامه نيز يك كلمه كليدي جديد وجود دارد: IN كه براي تست عضويت در يك مجموعه بكار مي‌رود. مجموعه‌اي كه بادستور IN بكار مي‌رود مي‌تواند دهها عضو داشته باشد و نوع اعضا نيز مي‌تواند رشته‌اي، عددي يا ... باشد. البته واضح است كه تمام اعضا بايد هم نوع باشند.

حال بعنوان يك مثال پيشرفته‌تر مي‌خواهيم مشخصات دانشجوياني را ببينيم كه اسم فاميل آنها به ‘ زاده’ ختم مي‌شود مانند عليزاده، محمد زاده و ... براي اين منظور بايد Query زير را نوشته و اجرا كنيم:

SELECT *
FROM family LIKE '% zadeh'

كاربراني كه با Access كار مي‌كنند بايد سطر آخر را به صورت زير تغيير دهند:

WHERE family LIKE '*zadeh'

در اين مثال از Wildcardها استفاده شده است كه قبلاً با مفهوم آن در DOS و Windows يا حتي Unix آشنا شده‌ايم (ls a*) . در Wildcard ،SQL هايي به شرح زير وجود دارند:

% (در Access از * استفاده كنيد): اين Wild card نشانگر هر تعدادي از كاراكترها (هر كاراكتري) مي‌باشد.

- (در Access از ? استفاده كنيد): اين Wildcard نشانگر يك كاراكتر مي‌باشد كه اين كاراكتر مي‌تواند هر كدام از كاراكترهاي مجاز كامپيوتر باشد.

جهت جستجو كردن فيلدهايي كه داراي يك الگوي (Pattern) خاصي هستند بايد از دستور LIKE و Wildcardها استفاده كرد. در مثال زير نام و سن تمام اساتيدي كه اسم آنها با Pe شروع مي‌شود، نمايش داده خواهد شد.

SELECT name, age
FROM teachers
WHERE name LIKE 'Pe%'

بنابراين مشخصات افرادي كه نام آنها مثلاً پدرام يا پيمان باشد در خروجي ليست خواهد شد.

3 – دستور ORDERBY :

دستور ORDERBY جهت Sort كردن ركوردهاي نمايش داده شده مورد استفاده قرار مي‌گيرد. با اين دستور مي‌توان مشخص كرد كه ركوردهايي كه قرار است نمايش داده شوند برحسب كدام فيلد بايد مرتب شوند. بعنوان مثال براي مشاهده كردن مشخصات اساتيدي كه سن آنها بيشتر از 29 سال مي‌باشد و در ضمن ليست خروجي بترتيب اسم فاميل نيز مرتب شده باشد بايد Query زير را اجرا كرد.

SELECT *
FROM teachers
ORDERBY family

در اين حالت افراد بترتيب اسم فاميل خود ليست خواهند شد. (از A تا Z) در صورتي كه بخواهيم ترتيب Sort شدن برعكس شود (از Z تا A) مي‌توان پس از دستور ORDERBY از كلمه كليدي DESC استفاده كرد، مانند مثال زير

SELECT *
FROM teachers
ORDERBY DESC name

در اين مثال Sort شدن بترتيب اسم و نه بترتيب فاميل انجام مي‌گيرد.

براي دستور ORDERBY مي‌توان چند فيلد تعريف كرد، در اين صورت اين دستور عمل Sort كردن را با در نظرگرفتن اولين فيلد انجام خواهد داد در صورتي كه چند ركورد داراي مقدار مشابهي در اين فيلد باشند ملاك مرتب سازي آنها فيلد دومي خواهد بود كه در دستور ORDERBY ذكر شده است، در صورتي كه اين فيلد نيز داراي مقادير مشابهي باشد ملاك تصميم‌ گيري فيلد سوم خواهد بود والي آخر.

بعنوان مثال در Query زير نام اساتيدي كه بيش از 30 سال دارند برحسب فاميل آنها مرتب مي‌شود در صورتي كه چند استاد داراي اسم فاميل يكساني باشند ملاك مرتب شدن، اسم كوچك آنها خواهد بود.

SELECT *
FROM teachers
WHERE age > 30
ORDERBY family, name

4 – استفاده از توابع:

در دستور SELECT علاوه بر تعريف فيلدها مي‌توان از عبارتهاي رياضي و يا توابع استاندارد SQL نيز استفاده كرد.

بعنوان مثال اگر ماليات بردرآمد پنج درصد باشد Query زير نام اساتيد و مالياتي را كه هر كدام مي‌پردازند را مشخص مي‌كند.

SELECT family, name, salary*5/100
FROM teachers

علاوه بر عبارتهاي رياضي مي‌توان از توابع استاندارد SQL نيز استفاده كرد، تعدادي از اين توابع عبارتند از:

تابع COUNT : تعداد فيلدها را برمي‌گرداند.

تابع SUM : مجموع يك فيلد عددي را برمي‌گرداند.

تابع AVG : ميانگين يك فيلد عددي را برمي‌گرداند.

تابع MIN : مينيمم يك فيلد عددي را برمي‌گرداند.

تابع MAX : ماكزيمم يك فيلد عددي را برمي‌گرداند.

بعنوان مثال اگر بخواهيم تعداد اساتيد و مجموع حقوقهايي را كه به آنها پرداخت شده است را ببينيم مي‌توانيم از Query زير استفاده بكنيم.

SELECT COUNT (name), SUM (Salary)
FROM teachers

5 – Queryهاي چند جدولي:

تمام Queryهايي كه تاكنون مشاهده كرديد، Queryهاي تك جدولي بودند بدين معني كه در هر Query فقط اطلاعات يك جدول مورد جستجو قرار مي‌گرفت. در SQL امكان نوشتن Queryهاي چند جدولي نيز وجود دارد. در اين حالت اطلاعات چند جدول بطور همزمان مورد جستجو قرار مي‌گيرد و حتي امكان مقايسه فيلدهايي از يك جدول با فيلدهايي از جدول ديگر نيز وجود دارد. اگر در بين جداولي كه در Query شركت داده مي‌شوند فيلدهاي هم نام وجود داشته باشد بايد نام آن فيلدها را Fully qualified كرد بدين معني كه ابتدا اسم جدول و سپس اسم فيلد را ذكر كرد. بين اسم جدول و اسم فيلد نيز بايد از يك كاراكتر نقطه (‘.’) استفاده كرد.

بعنوان مثال اگر بخواهيم ليست اساتيد و دانشجوياني كه داراي ارتباط فاميلي هستند را ببينيم مي‌توانيم از Query زير استفاده بكنيم:

SELECT *
FROM students, teachers
WHERE students.family = teachers. Family

و يا اگر بخواهيم ليست اساتيدي را مشاهده كنيم كه سن آنها از سن برخي از دانشجويان كمتر است، مي‌توانيم Query زير را اجرا كنيم:

SELECT teachers.family, teachers.name
FROM students, teachers
WHERE teachers.age < students.age

6 – كلام آخر:

كلام آخر اينكه زبان SQL برخلاف زبانهايي مانند C يا C++ يك زبان Case Sensitive نيست بدين معني كه به بزرگ يا كوچك بودن حروف حساس نمي‌باشد. بنابراين به راحتي مي‌‌توان دستورات و كلمات كليدي آنرا در هر برنامه‌اي با حروف كوچك يا بزرگ تايپ كرد.

WooKMaN
20-11-2005, 23:13
آموزش Java Script

جاوااسكريپت يك زبان مناسب براي انجام عملياتي چون چك كردن مقادير درون فرمها يا درست كردن منو براي حركت درون سايت يا حركت دادن يك شيئ درون صفحه و... است، اما بعضي از طراحان در استفاده از اين گونه كدها تا جايي پيش مي روند كه صفحه انباشته از كدهاي جاوااسكريپت ميشود. خوشبختانه جاوااسكريپت قدرت زيادي در جهت بهينه كردن كدها براي كاهش حجم يا بالا بردن سرعت اجرا به ما ميدهد. با استفاده از تكنيكهايي مثل فشرده سازي و مبهم سازي ميتوان 50% تا 90% حجم فايل جاوااسكريپت را كاهش داد.
چون فايلهاي جاوااسكريپت قسمتي از محتويات صفحات وب هستند، كاهش حجم آنها در كاهش زمان بارگذاري صفحات وب بسيار موثر است. البته در بعضي از مواقع هم افزايش سرعت اجراي كدها مهم است كه بايد اولويت هر كدام را بر اساس نياز انتخاب نمود.

چه زماني بايد كدها را بهينه كرد ؟
اغلب كدهاي جاوااسكريپت آنقدر كوچك هستند كه نيازي به بهينه سازي ندارند. در ابتدا كدهاي شما بايد درست كار كنند و خوانايي لازم را داشته باشند ) با بهره گيري از بهترين الگوريتمها (algorithms)و ساختمان داده هايي (Data Structures) كه براي شما امكان پذير است) آنگاه اگر متوجه شديد كه سرعت بارگذاري صفحات شما پايين است بايد به فكر بهينه سازي كدهاي خود باشيد.

آغاز بهينه سازي
جاوااسكريپت ميتواند از بيشتر تكنيكهاي بهينه سازي كه درCSS و HTML استفاده ميشود بهره ببرد. حذف فضاهاي خالي ، تكه تكه كردن و مبهم سازي ، تركيب چند فايل بصورت يكپارچه، از همه اين ترفندها به صورت تكي يا تركيبي از آنها ميتوان براي كاهش حجم كدها استفاده نمود. در كل با تركيب همه اين تكنيكها با هم، حجم كدها 50% تا 70% كاهش مي يابد. با استفاده ازCSS و HTML مجال بيشتري براي بهينه سازي كدهاي جاوااسكريپت بدست مي آيد، چون شما مي توانيد نام توابع و متغيرها و شي ها را به صورت دلخواه تعيين كنيد.
اگر حجم كدهاي جاوااسكريپت درون صفحه شما خيلي زياد باشد مطمعنا سرعت بارگذاري صفحه وب شما هم به همين اندازه پايين است. چون ارجاع به هر كدام از فايلهاي خارجي موجود در صفحه در قسمت head صفحه وب صورت مي گيرد در نتيجه تمامي فايلها بايد قبل از به نمايش در آمدن هر قسمتي از محتويات صفحه كه درون تگ body قرار دارند بارگذاري شوند، در اين صورت سرعت به نمايش در آمدن محتويات صفحه كاهش مي يابد. به همين دليل حجم فايلهاي .css و .js بسيار مهم است.

خوانايي برنامه
اولين عيبي كه به كدهاي بهينه شده گرفته ميشود پايين بودن خوانايي آنها است. براي حل اين مشكل ميتوان دوفايل جداگانه داشت، يكي فايل بهينه شده، براي استفاده در صفحه وب و ديگري (همان فايل اصلي) كه داراي خوانايي بالايي است، كه براي تغييرات يا مرورهاي بعدي كنار گذاشته مي شود.
بطور مثال دوفايل زير
code.js
code_o.js

كه فايل code_o.js همان فايل بهينه شده و فايل code.js همان فايل اصلي است.

تكنيكهاي بهينه سازي
1- حذف فضاهاي خالي موجود درون كدها
بطور مثال به كد زير دقت كنيد


function printArray(a) {
if (a.length == 0)
document.write(" Array is empty");
else {
for (var i = 0; i < a.length; i++) {
document.write(a[i] + "
");
}
}
}


پس از حذف فضاهاي خالي اينگونه ميشود


function printArray(a){
if(a.length==0)
document.write("Array is empty");
else{
for(var i=0;i document.write(a[i]+"
");
}
}
}


ويا حتي بهتر از آن


function printArray(a){
if(a.length==0)document.write("Array is empty");
else{for(var i=0;i document.write(a[i]+"
");}}}



2- كوتاه سازي يا حذف توضيحات درون كدها

به كدهاي زير دقت كنيد



function gotoFinList() {

// "SAVE & FINISH"
// this changes the bottom frameset to include a button
//to return to the homepage
// it also submits the form in the main frame that will
// then generate a list of pages
// added during content editing.


پس از كوتاه سازي


function gotoFinList() {

// chgs bottom frameset 2 incl button 2 ret 2 home
// also submits form in main form and gen list of pgs
// added during content editg


بهترين حالت حذف كامل توضيحات است


function gotoFinList() {



در قسمت بعد كه ادامه همين مطلب است تكنيكهاي ديگري در همين زمينه ارائه شده كه خواندن آنها را نيز به شما توصيه ميكنم.

WooKMaN
20-11-2005, 23:13
ادامه بحث Java Script


در اين قسمت مطالب قبلي را ادامه ميدهيم به دوستان عزيز خواندن قسمت اول اين مطلب را توصيه ميكنم

تكنيكهاي بهينه سازي
3- يكي از راههاي اضافه كردن كدهاي جاوااسكريپت به صفحات وب كه اغلب استفاده ميشود نوشتن كدهاي جاوااسكريپت در يك فايل جداگانه و سپس فراخواني آن در قسمت head صفحه است. مانند مثال زير


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title> Test Page</title>
<meta [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]"Content-Type" content="text/html; charset=utf-8">
<script language="JavaScript" src="code_o.js"> </script>
</head>
<body>
. . .
</body>
</html>


در اين صورت قبل از اينكه محتويات صفحه مورد نظر ما بارگذاري شود بايد فايل .js مورد نظر بطور كامل دريافت شود كه اين عمل باعث كاهش سرعت نمايش صفحات ميشود.

در صورتي كه كدهاي جاوااسكريپت مورد نظر ما خروجي خاصي براي نمايش درون صفحه نداشته باشند ميتوان بارگذاري كدها را به تاخير انداخت، بطور مثال كدهايي كه مقادير درون يك فرم وب را اعتبار سنجي ميكند. براي اين كار ميتوان از خصوصيت defer در تگ <script> بصورت زير استفاده نمود. البته اين خصوصيت فقط براي مرورگر IE (Internet explorer) قابل استفاده است.


<script language="JavaScript" src="code_o.js" defer="defer"> </script>


در اين صورت مرورگر بدون توجه به فايل جاوااسكريپت محتويات صفحه را بارگذاري ميكند و در نهايت به سراغ فايل .js ميرود.

يك راه بهتر براي صفحاتي كه داراي ترافيك بالايي هستند استفاده از SSI (Server Side Include) است. كار اين دستور مثل اين است كه كدها را مستقيما در جاي مورد نظر اضافه كرده باشيم. اين كار باعث ميشود كه حجم درخواستهاي مرورگر از سرويس دهنده كاهش يابد.

بطور مثال :


<script type="text/javascript">
<!--#include virtual="code_o.js" -->
</script>
</body>


4- بعضي از طراحان وب براي سازگاري كدهاي جاوااسكريپت با مرورگرهاي مختلف (مثل IE 4+ يا Netscape 4+ ويا DOM-based browsers) براي هر مرورگر كدهاي خاص همان مرورگر را استفاده ميكنند در اين حالت ميتوان بجاي نوشتن همه كدها در يك فايل حجيم و بزرگ، كدهاي مربوط به هر مرورگر را در فايلهاي جداگانه اي قرار داد (بطور مثال ie4.js و ns4.js و dom.js) و فقط از كدهاي مورد نياز استفاده كرد.
در كدهاي زير پس از تشخيص نوع مرورگر فقط فايل مربوط به همان مرورگر بارگذاري ميشود.


dom = (document.getElementById) ? true : false;
ns4 = (document.layers) ? true : false;
ie = (document.all) ? true : false;
ie4 = ie && !dom;

var src = '';
if (dom) src = '/dom.js';
else if (ie4) src = '/ie4.js';
else if (ns4) src = '/ns4.js';
document.write("<script src=" + src + "> <\/script> ");


5- كوتاه سازي و مختصر سازي كدها
با استفاده از نامهاي خلاصه سازي شده براي توابع و متغيرها و اشياء ميتوان حجم كدها را تاحد زيادي كاهش داد، البته براي اين كار بايد كدهاي HTML درون صفحه را نيز تصحيح كرد، كه اين كار با تغيير نام class و id مربوط به تگهاي مختلف درون صفحه امكان پذير است.
بطور مثال :


function validateParseAndEmail()
var firstButton


به كدهاي زير تبديل شده اند


function email()
var button1


و يا بهتر از آن كدهاي زير


function e()
var b


در اين حالت خوانايي برنامه بسيار پايين مي آيد. قبلا يك راه حل مناسب براي رفع اين مشكل بيان شد، يكي ديگر از راه حلها ايجاد يك جدول در فايل جداگانه است، بصورتي كه نام خلاصه شده درون برنامه و نام كامل هر متغر يا تابع در آن ذخيره شود تا در صورت نياز با مراجعه به جدول مورد نظر نام اصلي تابع يا متغير را تشخيص دهيم. البته دقت داشته باشيد كه اين فايل مخصوص برنامه نويس است و فقط براي خوانايي كدها ايجاد شده و جزئي از صفحات وب شما نيست.

خلاصه مطلب
با كاهش حجم فايلهاي جاوااسكريپت مورد استفاده سرعت بارگذاري صفحات وب نيز افزايش ميابد.
بطور كلي با روشهاي زير ميتوان حجم كدهاي جاوااسكريپت مورد استفاده در صفحات وب را تا حد زيادي كاهش داد:

- حذف فضاهاي خالي درون كدها
- حذف و يا خلاصه سازي توضيحات درون كدها
- استفاده از اسامي خلاصه شده براي متغيرها و توابع


اغلب تكنيكهاي ذكر شده در اينجا براي بهينه سازي حجم فايلهاي HTML و يا CSS نيز قابل استفاده هستند.

WooKMaN
20-11-2005, 23:14
ادامه بحث Java Script

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

Math.random() : يك عدد اتفاقي بين 0 و 1 را برميگرداند. بطور مثال عبارت زير يك عدد اتفاقي بين 0 و 25 را توليد ميكند.
25 * Math.random();

Math.round() : مقدار گرد شده يك عدد اعشاري را باز ميگرداند.
String.fromCharCode() : معادل كاراكتر ascii يك عدد را برميگرداند.
بطور مثال كد كاراكتر a عدد 97 است. در اين صورت خروجي تابع فوق با عدد 97 حرف a خواهد بود
String.fromCharCode(97) // return “a” character


? : : يك دستور شرطي است كه ابتدا عبارت قبل از علامت سئوال (?) را چك ميكند در صورتي كه مقدار آن true يا عددي غير صفر باشد خروجي آن مقدار قبل از علامت : است و در صورتي كه مقدار عبارت قل از ? false يا مقدار عددي صفر باشد خروجي آن مقدار بعد از علامت : است. بطور مثال

var exp1;
var temp="";

exp1 = true;
temp = exp1 ? "ON" : "OFF"
document.writeln (temp); // write ON

exp1 = false;
temp = exp1 ? "ON" : "OFF"
document.writeln (temp); //write OFF


+= :
اين دستور عمليات جمع و انتساب را باهم انجام ميدهد. مثلا هر دو عبارت زير با هم معادلند.

str = str + "end. "
str += "end. "


بعد از توضيحات كلي، كدهاي مروط به تابع مورد نظر را مي نويسيم.

function makepass(){
var str = "";
var len = 10;
var randomselect;
for (i = 1; i <= len; i++){
randomselect = Math.round(Math.random());
if (randomselect != 0)
charcode = Math.round(25*Math.random())+97;
else
charcode = Math.round(9*Math.random())+48;
str = str + String.fromCharCode(charcode);
}
return (str);
}


كار برنامه به اين صورت است كه در يك حلقه تكرار كه به تعداد طول كلمه عبور تكرار ميشود، در هر بار تكرار يك كاراكتر از كل كلمه عبور ايجاد ميشود، به اين صورت كه ابتدا يك عدد 0 يا 1 به صورت اتفاقي ايجاد ميشود اين عدد در متغير randomselect قرار مي گيرد. حال اگر عدد اتفاقي توليد شده مخالف 0 يعني 1 بود از يك حرف براي ايجاد كاراكتر فعلي كلمه عبور استفاده ميشود و در غير اين صورت از يك عدد در ايجاد كاراكتر فعلي كلمه عبور استفاده ميشود.
اما نحوه ايجاد يك كاراكتر يا يك عدد اتفاقي براي كلمه عبور به اين صورت است كه ابتدا يك عدد اتفاقي در محدوده مورد نظر ايجاد مي كنيم مثلا براي ايجاد يك حرف از حروف انگليسي (26 حرف داريم) به يك عدد اتفاقي بين0 تا 25 احتياج داريم حال در صورتي كه اين عدد را با عدد 97 كه كد حرف a است جمع كنيم يك حرف به صورت اتفاقي ايجاد كرده ايم .
در نهايت كاراكترهاي ايجاد شده را در كنار هم مي گذاريم تا كلمه عبور ساخته شود.

حال به سراغ بهينه سازي كدها مي رويم در اين مرحله از عبارت ? : بجاي if …else استفاده مي كنيم كدها به اين صورت در مي آيند.

function makepass_1(){
var str = "";
var len = 10;
var randomselect;
for (i = 1; i <= len; i++){
randomselect = Math.round(Math.random());
charcode = randomselect ? Math.round(25*Math.random())+97 : Math.round (9*Math.random())+48;
str = str + String.fromCharCode(charcode);
}
return (str);
}


بعد از آن بايد در صورت امكان بجاي متغييرها مقادير آنها را بكار بريم. كدها به صورت زير تغيير پيدا ميكنند.


function makepass_2(){
var str = "";
var len = 10;
for (i = 1; i <= len; i++){
charcode = Math.round (Math.random()) ? Math.round (25*Math.random())+97 : Math.round (9*Math.random())+48;
str = str + String.fromCharCode(charcode);
}
return (str);
}


در اين قسمت بجاي اينكه ابتدا يك عدد اتفاقي ايجاد كنيم و در يك متغير قرار دهيم و در نهايت مقدار آن متغير را به معادل ascii آن تبديل كنيم همه اين كارها را به صورت يكجا انجام مي دهيم. كدهاي زير ايجاد خواهند شد.


function makepass_3(){
var str = "";
var len = 10;
for (i = 1; i <= len; i++){
str = str + Math.round(Math.random()) ? String.fromCharCode (Math.round (25*Math.random())+97) : String.fromCharCode (Math.round (9*Math.random())+48);
}
return (str);
}


كدهاي نهايي به اين صورت در مي آيند.

function makepass_4(){
var str = "";
for (i = 1; i <= 10; i++)
str += Math.round(Math.random()) ? String.fromCharCode (Math.round (25*Math.random())+97) : String.fromCharCode (Math.round (9*Math.random())+48);
return (str);
}


اگر دقت كرده باشيد تا اينجا با روشهايي غير از روشهايي كه در بخشهاي قبلي بيان شده بودند حجم كدها را بهينه كرديم. البته همين تغييرات باعث كاهش قابل ملاحظه اي از حجم كدهاي جاوااسكريپت مورد نظر ما شد. اكنون كه نوشتن و ايجاد تغييرات بر روي كدها تمام شده ميتوان كد نهايي را با استفاده از قواعدي كه قبلا بيان شده بودند دوباره بهينه كرد. كه در نهايت كدهاي زير ايجاد خواهند شد.

function mp(){
var s="";
for (i=1;i<=10;i++)
s+=(Math.round(Math.random()))?String.fromCharCode (Math.round(25*Math.random())+97):String.fromCharC ode(Math.round(9*Math.random())+48);
return (s);
}

WooKMaN
20-11-2005, 23:34
مقدمه اي بر سي شارپ : قسمت اول

در طي سلسله مقالاتي مي خواهيم با C# بيشتر آشنا شويم. فرض اين مقالات بر اين است كه آشنايي مختصري با زبانهاي برنامه نويسي داريد ، هر چند كار ما تقريبا از صفر شروع مي شود و هدف آن سادگي هر چه بيشتر است.

C# از دو زبان C++ و Java متولد شده است! حاوي بسياري از جنبه هاي C++ مي باشد اما ويژگي هاي شيء گرايي خودش را از جاوا به ارث برده است.

C# اگرچه از C++ گرفته شده است اما يك زبان "خالص" شيء گرا (Object oriented) مي باشد. هر دو زبان ياد شده جزو زبانهاي هيبريد محسوب مي شوند اما طراحان C# اين مورد را به اندازه ي C++ مهم تلقي نكرده اند. يك زبان هيبريد اجازه ي برنامه نويسي با شيوه هاي مختلف را ميسر مي كند. دليل اينكه C++ هيبريد است ، اين است كه قرار بوده تا با زبان C سازگار باشد و همين امر سبب گرديده تا بعضي از جنبه هاي C++ بسيار پيچيده شوند.

زبان سي شارپ فرض اش بر اين است كه شما مي خواهيد تنها برنامه نويسي شيء گرا انجام دهيد و همانند C++ مخلوطي از برنامه نويسي رويه ايي (Procedural) و شيء گرا را نمي خواهيد به پايان برسانيد. بنابراين بايد طرز فكر خودتان را با دنياي شيء گرايي تطبيق دهيد. در ادامه خواهيد ديد كه در سي شارپ هر چيزي شيء است حتي يك برنامه ي سي شارپ.

برنامه ي اول :

Visual studio.net را اجرا كنيد و سپس در صفحه ي ظاهر شده New Project را برگزينيد. حالا از گزينه ي Visual C# projects قسمت Console applications را انتخاب نماييد. نامي دلخواه همانند ex01 را وارد نموده و سپس Ok نماييد. كد زير به صورت خودكار براي شما توليد خواهد شد:



using System;

namespace ex01
{
///
/// Summary description for Class1.
///
class Class1
{
///
/// The main entry point for the application.
///
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
}
}
}


اگر يك سري از مفاهيم آنرا متوجه نمي شويد اصلا مهم نيست! در مقالات آتي تمام اين موارد مفصل توضيح داده خواهند شد.
متد استاندارد Main در اينجا قسمتي است كه عمليات اصلي برنامه در حالت Console ( شبيه به برنامه هاي تحت داس اما 32 بيتي ) در آن انجام مي شود.
بدون متد Main برنامه هاي سي شارپ قادر به اجرا نخواهند بود. نوع آن در اينجا void تعريف شده است يعني اين متد خروجي ندارد. حتي اگر برنامه هاي استاندارد ويندوز را هم بخواهيد با C# بنويسيد بازهم متد Main حضور خواهد داشت ، هر چند به صورت خودكار ويژوال استوديو آنرا توليد مي كند.

طريقه ي نوشتن توضيحات (Comments) در سي شارپ همانند C++ مي باشد يعني :



/* any comments */


ويا


// any comments


و تنها برنامه نويس براي نوشتن توضيحاتي در مورد كدهاي خود از آنها استفاده مي كند و در خروجي برنامه ظاهر نمي شوند.

فعلا براي پايان قسمت اول از شيء Console و متد WriteLine آن براي نمايش يك جمله ي ساده استفاده مي كنيم. راجع به متدها ، متغيرها و غيره در آينده بيشتر صحبت مي كنيم.
در آخر برنامه ي ما چيزي شبيه به عبارت زير مي باشد:



using System;

namespace ex01
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("Hello C#!");
}
}
}


دكمه ي F5 را فشار دهيد تا برنامه اجرا شود.

تعريف متغيرها در سي شارپ:

سي شارپ عناصري را كه بكار مي گيرد همانند اعداد و كاراكترها ، به صورت نوع ها (Types) طبقه بندي مي كند. اين انواع شامل موارد زير مي شوند :
نوع هاي پايه ايي از پيش تعريف شده مانند اعداد و غيره.
نوع هاي تعريف شده توسط كاربر كه شامل STRUCT ها و ENUM ها مي شوند.

نحوه ي تعريف متغيرها از نوع هاي پايه ايي از پيش تعريف شده :
همانطور كه مي دانيد از متغيرها براي نگهداري اطلاعات استفاده مي شود. در سي شارپ ابتدا نوع متغير و سپس نام متغير و در آخر يك سمي كولون بكار برده مي شود. براي مثال :


int a;


كه در اينجا متغير a بعنوان يك متغير حاوي اعداد صحيح تعريف شده است.
نكته ي مهمي كه در اينجا حائز اهميت است ، مقدار دهي اوليه ي متغيرها مي باشد. در غير اينصورت كامپايلر سي شارپ برنامه را بايك خطا متوقف مي كند. دليل اين امر هم اين است كه از استفاده از متغيرهاي بدون مقدار در طول برنامه جلوگيري شود تا ميزان خطاهاي در حين اجرا كاهش يابد.

نوع هاي داده اي پايه ي زير در در سي شارپ به صورت پيش فرض مهيا هستند:

object : نوعي است نامحدود كه مي تواند تمام انواع ديگر را نيز شامل شود. مثال :


object = null;


string : رشته ؛ در اينجا يك رشته توالي كاراكترهاي يونيكد مي باشد. مثال :


string s= "hello";


sbyte : نوع داده ايي صحيح 8 بيتي علامت دار.
byte : نوع داده ايي صحيح 8 بيتي بدون علامت. مثال :


sbyte val = 12;


short : نوع داده ايي صحيح 16 بيتي علامت دار.
ushort : نوع داده ايي صحيح 16 بيتي بدون علامت. مثال :


short val = 12;


int : نوع داده ايي صحيح 32 بيتي علامت دار.
unit : نوع داده ايي صحيح 32 بيتي بدون علامت. مثال :


int val = 12;


long : نوع داده ايي صحيح 64 بيتي علامت دار.
ulong : نوع داده ايي صحيح 64 بيتي بدون علامت. مثال :


Long val1 = 12; long val2 = 34L;


كلا در اينجا u به معناي unsigned است.

float : نوع اعشاري با single precision .
double : نوع اعشاري با double precision . مثال :


float val = 1.23f;


bool : نوع داده ايي Boolean كه مي تواند true و يا false باشد. مثال :


Bool val = true;


char : كاراكتر، دراينجا char يك كاراكتر يونيكد است.


char val = 'h';


به نحوه ي تعريف كاراكتر ها و همچنين رشته ها در سي شارپ دقت كنيد.

decimal : نوع داده ايي دسيمال با 28 رقم معني دار.


decimal val = 1.23M;


يك نكته :

- بهتر است هنگام تعريف يك متغير ، نامي با مسما براي آن انتخاب شود تا در هنگام كار خواندن كد ساده تر گردد. همچنين رسم شده است كه نوع متغير را به صورت خلاصه به نام متغير اضافه مي كنند. براي مثال بجاي FirstName بهتر است بنويسيم strFirstName . به اين نوع نگارش Hungarian notation مي گويند.
- تمام نوع هاي پيش فرض تعريف شده در سي شارپ شيء هستند. در آينده بيشتر در اين مورد صحبت خواهيم كرد.

مثال اين قسمت :

يك برنامه ي console جديد در را VS.NET باز كنيد. نام آنرا در ابتدا ex02 انتخاب نماييد. در اينجا مي خواهيم دو متغير رشته ايي و صحيح را تعريف و سپس در خروجي نمايش دهيم.

كد نهايي به صورت زير مي باشد:


using System;

namespace ex02
{
///
/// Summary description for Class1.
///
class Class1
{
///
/// The main entry point for the application.
///
[STAThread]
static void Main(string[] args)
{
int intVar1 = 0;

int intVar2;
intVar2=1;

int intV3=15 , intV4 = 12;

string strText1 = "abcd";

Console.WriteLine(
"The value for variables are : \n intVar1="+intVar1 +
"\n intVar2="+ intVar2 +
"\n intV3=" + intV3 +
"\n intV4=" + intV4 +
"\n strText1=" + strText1);

Console.WriteLine("\n\n Press any key to terminate");
Console.ReadLine(); // pause screen!

}
}
}


نكاتي در مورد كد فوق:

- بك اسلش ان ، در زبانهاي مشتق شده از سي به معناي new line مي باشد.
- در كد فوق نحوه ي تعريف چند متغير در يك خط و حالتهاي مقدار دهي مختلف را ملاحظه مي كنيد.
- از متد ReadLine براي نگه داشتن خروجي و مشاهده ي آن در اينجا استفاده كرديم.
- عادت كنيد به صورت دندانه دار كد بنويسيد. اينكار خوانايي كد را صد برابر مي كند. در اينجا كدهاي داخل متد main ، كاملا چند دندانه از آكولادهاي باز و بسته كردن آن جلو تر هستند.
- در كد بالا در متد WriteLine اعداد و رشته ها با هم جمع شده اند! اين مورد بدليل وجود overload هاي زياد اين تابع و ... ميسر گشته است. اصلا به آن دل نبنديد! چون در آينده كامپايلر سي شارپ اگر چنين اعمالي را در جاهاي ديگري مرتكب شويد به شدت با شما برخورد خواهد كرد!! براي جمع كردن اعداد با رشته ها حتما بايد عدد به رشته تبديل گردد و بعد ... . در اين مورد در مقالات بعدي بحث خواهد گرديد.

در مورد كلاسها و using و namespace و غيره در آينده بيشتر صحبت خواهيم كرد.

WooKMaN
20-11-2005, 23:34
مقدمه اي بر سي شارپ : قسمت دوم

در اين قسمت مي خواهيم با يك سري از اصول اوليه ي شيء گرايي در سي شارپ كمي آشنا شويم. لازم به ذكر است ، بسياري از مواردي كه در اين قسمت مطرح مي شوند فقط براي آشنايي شما است و در آينده بيشتر بحث و مرور خواهند شد.

آشنايي با فضاهاي نام (NameSpaces) :

فضاهاي نام روشي براي مديريت كد نويسي هستند. براي مثال آنها ايجاد شده اند تا تداخلي بين نام هاي توابع در برنامه شما رخ ندهد. اين مساله در پروژه هاي بزرگ خود را نشان مي دهد و ممكن است دو آيتم در يك پروژه نام هاي يكساني را پيدا كنند. بدين وسيله اين شانس تصادم و تداخل كاهش پيدا مي كند. براي ايجاد يك فضاي نام به صورت زير عمل مي شود:



namespace anyName
{
……..

Class anyClassName
{
……….
}

…….

}



يكي از فضاهاي نام پايه اي در دات نت فريم ورك ، فضاي نام System مي باشد. براي استفاده از آن مي توان از كد زير كمك گرفت :


using System;


تمام فضاهاي نام به صورت پيش فرض public مي باشند و در خارج از كد شما قابل دسترسي هستند. روش استفاده از آنها به صورت زير است:


ProjectName.NameSpace.ClassName.MemberName


نكته :
اگر دقت كرده باشيد هنگامي كه كرسر ماوس را روي هر آيتمي در منوي autocomplete نگه مي داريد و يا آنرا انتخاب مي كنيد يك راهنماي كوچك نمايش داده مي شود كه در حقيقت كامنت مربوط به آن تابع مي باشد. روش نوشتن چنين كامنت حرفه اي كه در منوهاي ويژوال استوديو ظاهر شود به صورت زير است كه بهتر است (!) قبل از هر تابع يا خاصيت يا كلاس و .... نوشته شود


///
///
///
///


كلاس ها :

چون سي شارپ تمام سر و كارش با كلاس ها است بنابراين بايد در مورد نحوه ي تعريف و استفاده از آنها تسلط كافي داشته باشيم.

يك پروژه ي جديد console در VS.NET باز كنيد و نام آنرا در ابتدا ex03 وارد نماييد.
بعد از باز شدن پروژه ، از منوي Project گزينه ي Add class را انتخاب كنيد تا كلاسي جديد به نام clsDate.cs را اضافه نماييم. ساختار فايل ايجاد شده توسط VS.NET به صورت زير است :


using System;

namespace ex03
{
///
/// Summary description for clsDate.
///
public class clsDate
{
public clsDate()
{
//
// TODO: Add constructor logic here (chashm!)
//
}
}
}


تابع يا متد clsDate كه در اينجا به صورت پيش فرض ايجاد شده است اصطلاحا سازنده (constructor) نام دارد. اين تابع هر بار كه يك شيء جديد از كلاس مي سازيم به صورت خودكار اجرا مي شود.

از اين كلاس مي خواهيم براي نمايش تاريخ/ ساعت و غيره استفاده كنيم.

براي مثال مي خواهيم تاريخ جاري سيستم را به صورت يك خاصيت از اين كلاس دريافت كنيم. براي اين منظور كد زير را به برنامه اضافه مي نماييم:


public string currentSystemDate
{
get
{
return System.DateTime.Today.ToString() ;
}
}


توضيح كد فوق :

خاصيتي را كه مي خواهيم از برنامه دريافت كنيم با كلمه ي كليدي get معرفي مي نماييم. هر چيزي كه اين قسمت برگرداند خروجي currentSystemDate خواهد بود. اين دستور زبان كه در بالا معرفي شد استاندارد است و در همه جا به يك صورت تعريف و بكار برده مي شود. پس شكل آنرا به خاطر بسپاريد.
از كلمه ي كليدي return براي برگرداندن يك خروجي از خاصيت و يا تابع استفاده مي شود.

براي استفاده از اين خاصيت جديد ، در فايل Class1.cs كه متد main برنامه ي ما در آنجا قرار دارد به صورت زير عمل مي كنيم :


clsDate m_var = new clsDate(); // initialize variable
Console.WriteLine ( m_var.currentSystemDate );
Console.ReadLine();//pause!


توضيح كد فوق :

براي استفاده از يك كلاس بايد يك متغير از آن را تعريف كنيم. در هر زباني يك سري نوع هاي استاندارد مانند int و string و غيره وجود دارند. كلاس هم در حقيقت يك نوع داده ي بسيار بسيار قدرتمند به شمار مي آيد. براي تعريف يك متغير از نوع جديد روش كار مانند سابق است. براي مثال زماني كه يك متغير عدد صحيح را تعريف مي كنيد به صورت زير عمل مي شود :


int i=0;


راي تعريف يك متغير از نوع داده اي كه خودمان تعريف كرده ايم نيز بايد به همين صورت عمل شود.


clsDate m_var = new clsDate();


از كلمه ي كليدي new اينجا به صورت استاندارد براي مقدار دهي اوليه به اين متغير جديد استفاده مي نماييم.

سپس به روش دستيابي به اين خاصيتي كه به كلاس اضافه كرده ايم مي رسيم.


m_var.currentSystemDate


كلا چه يك خاصيت و يا يك متد را به كلاس اضافه نماييم براي دستيابي به آن از عملگر نقطه پس از ذكر نام متغير تعريف شده از نوع كلاس خود ، استفاده مي نماييم. براي استفاده از خاصيت ها نيازي به آوردن () بعد از ذكر نام خاصيت نمي باشد.

عموما از خاصيت ها براي برگرداندن و يا تنظيم يك مقدار ساده استفاده مي شود و در آنها عمليات پيچيده اي مد نظر نمي باشد.

توضيحي در مورد ; () System.DateTime.Today.ToString
استفاده از خواص :

شما به ويژگي هاي يك شيء با استفاده از خواص آن مي توانيد دسترسي پيدا كنيد. يك property عضوي است كه امكان دسترسي به ويژگي شيء يا كلاس را فراهم مي كند. براي مثال طول يك رشته (string) ، سايز يك فونت ، عنوان يك فرم و نام يك مصرف كننده ، خاصيت هستند .
بسياري از اشياء ذاتي دات نت فريم ورك ، خواص مفيد زيادي را به همراه دارند. براي مثال شيء DateTime را در نظر بگيريد. با استفاده از خاصيت Today آن مي توان تاريخ جاري سيستم را بدست آورد. براي استفاده از يك خاصيت لازم است تا كلاس تعريف كننده شيء در برنامه مهيا باشد. منظور همان استفاده از فضاي نام مربوطه مي باشد. پس از وارد كردن فضاي نام كلاس مورد نظر مي توانيد از شيء و خواص آن استفاده كنيد. دو راه وجود دارد يا به صورت كامل تمام موارد بايد ذكر شوند مانند System.DateTime.Now; و يا با وارد كردن فضاي نام System كوتاه سازي صورت مي گيرد.
براي استفاده از هر متد و يا شيء ايي در سي شارپ بايد اين شيء قابل دسترسي باشد. براي مثال شيء Console كه از آن براي چاپ كردن خروجي بر روي صفحه ي نمايش استفاده مي كنيم در فضاي نام System واقع شده است. يا بايد در ابتداي برنامه ذكر كرد using System ; و سپس خيلي راحت از اين شيء استفاده كرد و يا مي توان اينكار را انجام نداد و نوشت : System.Console و الي آخر. با ذكر فضاي نام در ابتدا با استفاده از using مي توان خلاصه نويسي كرد.

نتيجه ي نهايي مثال اين فصل :

محتويات فايل Class1.cs :


using System;

namespace ex03
{
///
/// Summary description for Class1.
///
class Class1
{
///
/// The main entry point for the application.
///
[STAThread]
static void Main(string[] args)
{
clsDate m_var = new clsDate(); // initialize variable
Console.WriteLine ( m_var.currentSystemDate );

Console.ReadLine();//pause!
}
}
}


محتويات فايل clsDate.cs كه به برنامه اضافه كرديم:


using System;

namespace ex03
{
///
/// Summary description for clsDate.
///
public class clsDate
{
public clsDate()
{
//
// TODO: Add constructor logic here
//
}

public string currentSystemDate
{
get
{
return System.DateTime.Today.ToString() ;
}
}


}
}

WooKMaN
20-11-2005, 23:36
مقدمه اي بر سي شارپ : قسمت سوم

ساختارهاي تصميم گيري :

در بسياري از موارد هنگام برنامه نويسي لازم است تا از عبارات شرطي استفاده كنيم. براي انجام اينكار دو روش عمده وجود دارد. استفاده از if و يا switch . از if بيشتر براي مقايسه هايي تكي و كوچك استفاده مي شود و حاصل مقايسه ي آن يا true است و يا false . از عبارت switch هنگامي استفاده مي شود كه مقايسه هاي متعددي بايد در مورد يك مقدار صورت گيرد.
هر دو عبارت if و switch توسط عبارتهايي Boolean كنترل مي شوند ( true و يا false ) . در هنگام استفاده از if اگر عبارت Boolean حاصل اش true باشد اولين قسمت شرط اجرا مي شود و سپس برنامه از انتهاي if ادامه پيدا مي كند. اگر حاصل عبارت Boolean مساوي false باشد كنترل برنامه به قسمت else منتقل مي شود.

مثال :

يك پروژه ي جديد console باز كنيد و نام آنرا ex04 بگذاريد. سپس كد زير را در آن وارد و جرا كنيد :


using System;

namespace ex04
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("Enter 1 character to be evaluated");

char cUserInput = (char) Console.Read();

if ( char.IsDigit( cUserInput ) )
Console.WriteLine("The char is a number!");
else
Console.WriteLine("The char is not a number!");

}
}
}


نكاتي در مورد كد فوق :

1- سي شارپ به كوچكي و بزرگي حروف حساس است . براي مثال cUserInput با cUserinput فرق مي كند.
2- حتما بايد بعد از if پرانتزها ذكر گردد.
3- حتما بايد داخل if يك عبارت Boolean ذكر شود مانند if(x>5) .
4- در سي شارپ مقايسه ي تساوي دو عبارت با == و انتساب با = انجام مي شود. ( موارد 1 و 4 مواردي هستند كه اغلب تازه كاران با آن مشكل دارند! ) براي مثال if(i==3) صحيح است اما if(i=3) در سي شارپ معنايي ندارد.
5- اگر بعد از if يك خط كد قرار گيرد نيازي به آوردن آكولاد ها نيست. هنگامي نياز به آكولادها مي باشد كه بيش از يك خط بايد بعد از if قرار گيرد.
6- در سي شارپ همانند اسلاف خودش براي تبديل نوع هاي داده ايي مي توان به صورت زير نيز عمل كرد : (char) Console.Read() ; يعني دريافتي Read به char تبديل مي شود .در اين مورد باز هم صحبت خواهد شد.
7- همانطور كه ذكر شد در سي شارپ همه چيز شيء است حتي نوع هاي پايه ايي مانند char . با استفاده از متد IsDigit آن مي توان چك كرد كه آيا ورودي آن عدد است يا خير؟ ( در مورد متدها صحبت خواهد شد )

استفاده از switch :

بهتر است اين مورد را با يك مثال دنبال كنيم.
پروژه ي سي شارپ جديدي به نام ex05 در حالت console در VS.NET باز كنيد. دراينجا مي خواهيم يك كلاس جديد تعريف كرده و توسط خاصيتي كه در آن ايجاد مي كنيم متوجه شويم روز جاري مطابق سيستم چه روزي است .
يك كلاس جديد از منوي پروژه ،‌با استفاده از گزينه ي Add class به برنامه اضافه كنيد و نام آنرا در ابتدا clsDate بگذاريد.


using System;

namespace ex05
{
///
/// Summary description for clsDate.
///
public class clsDate
{
public clsDate()
{
//
// TODO: Add constructor logic here
//
}

public string systemDayOfWeek
{
get
{

string res="";
switch( System.DateTime.Now.DayOfWeek.ToString())
{
case "Saturday" :
res = "شنبه";
break;

case "Sunday" :
res = "يک شنبه" ;
break;

case "Monday":
res = "دوشنبه";
break;

case "Tuesday":
res = "سه شنبه";
break;

case "Wednesday":
res = "چهار شنبه";
break;

case "Thursday":
res = "پنج شنبه";
break;

case "Friday":
res = "جمعه" ;
break;
}

return res ;
}

}


}
}


هنگام ذخيره كردن اين كد ويژوال استوديو به شما اخطار مي دهد كه كد داراي حروف يونيكد است. از منوي فايل گزينه ي advanced save options را انتخاب كنيد. در اينجا مي توان نوع ذخيره سازي را يونيكد انتخاب كرد.

براي استفاده از كلاس فوق مانند مطالبي كه در قسمت قبل گفته شد عمل مي كنيم :


using System;

namespace ex05
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
clsDate m_var = new clsDate();
Console.WriteLine( m_var.systemDayOfWeek );
Console.ReadLine();

}
}
}


هر چند حالت console يونيكد را پشتيباني نمي كند ولي اصل برنامه براي ما مهم است و در آينده بيشتر از آن استفاده خواهيم كرد.

همانطور كه ملاحظه كرديد اگر از switch استفاده نمي شد بايد از 7 عدد if ‌استفاده مي گرديد كه اصلا ظاهر حرفه اي و شكيلي نداشت!
با استفاده از عبارت زير كار مقايسه شروع مي شود. روز سيستم در يافت شده و وارد بدنه ي switch مي گردد. سپس توسط case ها چك مي شود تا تساوي آن با عبارت بعد از case به اثبات برسد.


switch( System.DateTime.Now.DayOfWeek.ToString())


اگر هر كدام از عبارات بعد از case صحيح بودند كار پس از آن كه در اينجا انتساب است انجام شده و سپس توسط break كنترل برنامه از switch خارج مي شود و ادامه ي كار دنبال مي گردد.
اگر هيچكدام از case ها صحيح نبودند مي توان از گزينه ي default هم در صورت نياز استفاده كرد. اين حالت در يك چنين مواقعي اجرا مي گردد.

WooKMaN
20-11-2005, 23:38
مقدمه اي بر سي شارپ : قسمت چهارم

آرايه ها در سي شارپ :

هنگامي آرايه ها ايجاد مي شوند كه بخواهيم با مجموعه اي از اطلاعات همجنس كار كنيم. براي نمونه از يك آرايه براي ذخيره تعدادي كاراكتر مي خواهيم استفاده نماييم. آرايه ها هم يك نوع متغير هستند پس بايد تعريف و مقدار دهي اوليه شوند ، نوع و تعداد اعضاي آنها نيز بايد معين گردد.
فرض كنيد 10 داده ي هم جنس داريم ( براي مثال رشته (string) ) و مي خواهيم آنها را ذخيره كنيم. يا مي توان 10 متغير مختلف را تعريف كرد و سپس تك تك آنها را مقدار دهي نمود و يا يك آرايه تعريف نمود و سپس در خانه هاي مختلف آن اين ده عضو را چيد. اين مطلب زماني حائز اهميت مي شود كه داده هاي همجنس و به نوعي مرتبط ما تعداد زيادي داشته باشند.

براي تعريف آرايه چندين راه مختلف وجود دارد :
براي تعريف آرايه ابتدا نوع آنرا مشخص مي كنيد سپس [] را بايد جلوي تعريف نوع بگذاريد اين دستور زبان است و چون چرا ندارد! در زبان سي كمي متفاوت بود. اين كروشه ها بعد از نام متغير مي آمدند. و سپس در اينجا نام يك متغير را كه بعدا به آن ارجا مي دهيم خواهيد گذاشت. براي مثال



int[] table; // not int table[];



حد پايين آرايه صفر بوده براي مثال اگر آرايه chrData[] ده عضو داشته باشد، اولين عضو آن chrData[0] و آخرين عضو آن chrData[9] است.
مطلب ديگري كه در مورد آرايه ها خيلي مهم است اندازه ي آن است. يعني يك آرايه حاوي چند خانه ي خالي است كه ما اجازه داريم آنرا پر كنيم. مثال :



int[] numbers; // declare numbers as an int array of any size
numbers = new int[10]; // numbers is a 10-element array
numbers = new int[20]; // now it's a 20-element array


1- تعريف آرايه اي از رشته ها و مقدار دهي اوليه آن.



String[] strData = new string[2];


2- تعريف و مقدار دهي اوليه



string [] strData = { "1234","abcd" };


كه آرايه اي از نوع رشته اي به طول 2 عضو با مقدار دهي اوليه ايجاد شده است. در اين حالت نيازي به تعيين طول آن نمي باشد.

3- روشي ديگر براي مقدار دهي اوليه



strData[0] = "1234";
strData[1] = "abcd";


مثال : يك پروژه ي جديد Console سي شارپ را باز كنيد و نام آنرا در ابتدا ex06 بگذاريد. در اين مثال مي خواهيم نحوه ي كار با آرايه ها را مرور كنيم :



using System;

namespace ex06
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
string[] sGoalList = new string[3];
string sReplyStatement = "You have choosen Goal '";

// Store goals in the array
sGoalList[0] = "Hike the Appalachian Trail";
sGoalList[1] = "Run the marathon";
sGoalList[2] = "Give $1 million to worthwhile causes";

// Store response to goals in the array
//(declaring and initializing on same line)
string[] sGoalResponse = {
"If you are staring from GA, you should get "
+ "started in early spring, so you will "+
"not get caught in snow.",
"Make sure that you have a good pair of shoes.",
"Start saving as soon as possible."};

// Give the user a list of goals to choose from
Console.WriteLine("GOAL LIST");

for(int i = 0; i < sGoalList.Length; i++)
{
Console.WriteLine("Goal " + i +
" - " + sGoalList[i]);
}


// Request the user to choose a goal.
Console.WriteLine (""); // Write an empty line for space
Console.Write("Please choose the number of the "
+ "goal that you want to achieve [0,1,2]: ");

Console.ReadLine();

}
}
}


نكاتي در مورد كد فوق :
1- نحوه ي استفاده از عملگر + را براي اتصال رشته هاي بلند در كد فوق مي توان ديد.
2- در سي شارپ پايان خط سمي كولون مي باشد. بنابراين نگراني در مورد چند خطي شدن يك دستور وجود ندارد.
3- هنگامي كه آرايه اي را با مقادير درون آكولادها ، مقدار دهي اوليه مي كنيد لزومي ندارد طول آن آرايه را مشخص كنيد ؛ مانند آرايه sGoalResponse در بالا. در غير اينصورت حتما بايد طول يك آرايه را كه معرف تعداد خانه هاي خالي آن است ، معرفي كنيد مانند آرايه sGoalList .
4- فعلا حلقه ي for را در اين مثال بخاطر داشته باشيد تا در مقاله ي بعدي راجع به آن صحبت كنيم

WooKMaN
20-11-2005, 23:42
مقدمه اي بر سي شارپ : قسمت پنجم

حلقه ها در سي شارپ :

مقدمه :

اگر نياز باشد تا قطعه اي از كد بيش از يكبار اجرا شود نياز به استفاده از حلقه ها مي باشد. براي مثال فرض كنيد آرايه اي به طول 1000 تعريف كرده ايد. اكنون مي خواهيد آنرا با هزار عدد متوالي پركنيد. بديهي است كه روش زير كارآمد نيست! :


int[] intData = new int[1000];
intData[0]=0;
.
.
.
intData[999]=1000;


نوشتن اين خطوط متوالي احتمالا با كپي و پيست و اصلاح آن حداقل نيم ساعت طول مي كشد! بنابراين نياز به وسيله اي حس مي شود كه بتوان بوسيله ي آن امثال اينگونه كارها را انجام داد.

تعريف حلقه ها و استفاده از آنها :

براي تعريف حلقه ها ابزارهاي متعددي مانند while, do , for , foreach وجود دارند. استفاده و انتخاب آنها بستگي به سليقه ي شما و منطق برنامه دارد. در هر حال يك مساله بديهي است كه همواره بيش از يك راه حل براي يك مساله وجود خواهد داشت.

استفاده از حلقه ي for :

عموما كدنويسي را با كد نويسي مي توان آموخت! بنابراين در مورد انواع حلقه ها مثالهايي ارائه خواهد گرديد.

يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex07 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


using System;

namespace ex07
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
int[] intData = new int[1000];

for (int i=0 ; i<1000 ; i++ )
intData[i]=i;


for(int i=0 ; i< intData.Length ; i++)
{
int j = intData[i];
Console.WriteLine("intData[" + i + "]=" + j);
}

Console.ReadLine();

}
}
}


توضيحاتي در مورد كد فوق :
1- براي تعريف حلقه ي for همانطور كه مي بينيد بايد تعداد بار اجراي حلقه ( اينجا از 0 تا 999 است ) و همچنين نحوه ي رسيدن از 0 به 1000 را مشخص كرد ( در اينجا i++ است يعني هر بار يك واحد به شمارشگر حلقه اضافه مي شود. )
2- در زبان سي i++ يعني i=i+1 و i-- يعني i=i-1 و كلا i-=n يعني i=i-n و به همين ترتيب. براي مثال i*=n يعني i=i*n و i+=n يعني i=i+n و ...
3- اگر پس از حلقه ي for يك خط كد داشته باشيم نيازي به آكولاد نيست (مانند قسمت اول كد). ولي اگر تعداد خطوط مربوط به بدنه ي for زياد بود بايد حتما از آكولاد استفاده شود (مانند قسمت دوم كد). (اين قاعده اي كلي است در زبانهاي مشتق شده از زبان سي در مورد هر چيزي!)
4- فرض كنيد در قسمت اول كد بالا بجاي 1000 مي نوشتيد 1001 . سريعا با يك خطاي زمان اجرا مواجه مي شديد. زيرا مي خواستيد به عضوي از آرايه دسترسي پيدا كنيد كه تعريف نشده است. راه مدرن چك كردن اين مسائل استفاده از خاصيت Length آرايه است كه در قسمت دوم كد در عمل مشاهده مي نماييد. هميشه از اين روش استفاده كنيد.
5- حلقه ي اول يعني اينكه كار پر كردن آرايه intData را از صفر تا 999 يكي يكي (i++) انجام بده.

استفاده از حلقه ي while :
يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex08 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


using System;

namespace ex08
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
int n = 1;

while (n < 6)
{
Console.WriteLine("Current value of n is {0}", n);
n++;
}

Console.ReadLine();
}
}
}


توضيحاتي در مورد كد فوق :
1- حلقه ي while در بالا كار انجام حلقه را تا هنگامي انجام مي دهد كه شرط ذكر شده در ابتداي آن صادق و برقرار باشد. يعني در حلقه ي فوق تا وقتي n<6 است اين حلقه ادامه خواهد يافت.
2- حلقه ي while صفر يا بيشتر بار ممكن است اجرا شود.
3- در كد فوق از {0} استفاده گرديده است. متد WriteLine به شما اين اجازه را مي دهد كه n تا آرگومان براي آن تعريف كنيد و مقادير هر كدام را كه خواستيد در كد نمايش دهيد از {x} استفاده كنيد. در اين مورد مقدار آرگومان x ام نمايش داده مي شود.

استفاده از حلقه ي do :

يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex09 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


using System;

namespace ex09
{

class Class1
{
[STAThread]
static void Main(string[] args)
{
int x;
int y = 0;

do
{
x = y++;
Console.WriteLine(x);

}while(y < 5);

Console.ReadLine();

}
}
}


توضيحاتي در مورد كد فوق :
1- اين حلقه به حلقه ي do…while معروف است و هر دو جزء آن بايد ذكر گردد.
2- اين حلقه تا زماني كه شرط ذكر شده در قمست while صحيح است ادامه مي يابد.
3- اين حلقه در ابتداي كار بدون توجه به قسمت while حداقل يكبار اجرا مي شود. (مثال زير را اجرا نماييد)


int n = 10;
do
{
Console.WriteLine("Current value of n is {0}", n);
n++;
} while (n < 6);


استفاده از حلقه ي foreach :

يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex10 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


using System;

namespace ex10
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
int odd = 0, even = 0;
int[] arr = new int [] {0,1,2,5,7,8,11};

foreach (int i in arr)
{
if (i%2 == 0)
even++;
else
odd++;
}

Console.WriteLine(
"Found {0} Odd Numbers, and {1} Even Numbers.",
odd, even) ;

Console.ReadLine();

}
}
}


توضيحاتي در مورد كد فوق :
1- از foreach براي حركت در بين اعضاي يك آرايه (مانند مثال بالا) و يا مجموعه ايي از اشياء استفاده مي شود (روشي شكيل ، مدرن و مطمئن! و تقريبا به ارث رسيده از ويژوال بيسيك!!).
2- در زبانهاي مشتق شده از C ، عملگر % ، باقيمانده را محاسبه مي كند.
3- در كد فوق با استفاده از حلقه ي foreach تك تك اعضاي آرايه در مورد زوج و يا فرد بودند مورد بررسي قرار گرفته اند و تعداد اعضاي زوج و فرد در آخر نمايش داده مي شود

WooKMaN
21-11-2005, 13:53
مقدمه اي بر سي شارپ : قسمت ششم

دو مورد تكميلي در مورد حلقه ها در سي شارپ :

1- هر جايي خواستيد به هر دليلي حلقه را پايان دهيد مي توانيد از دستور break; استفاده كنيد. در اين حالت به صورت آني حلقه خاتمه يافته و كدهاي ادامه ي برنامه پس از حلقه اجرا مي شوند.
2- نحوه ي استفاده از دستور continue : فرض كنيد حلقه ي شما در راند 15 خودش است! حالا در اين راند شما مي خواهيد يك سري از دستورات درون حلقه اجرا نشوند و حلقه به راند بعدي منتقل شده و كارش را ادامه دهد. اينجا است كه از دستور continue استفاده مي شود. بهتر است به يك مثال ساده در اين زمينه توجه كنيم.

مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex11 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


using System;

namespace ex11
{
class Class1
{
[STAThread]
static void Main(string[] args)
{

Console.WriteLine(
"for (int i = 1; i <= 100; i++) -> break at i==5" );
for (int i = 1; i <= 100; i++)
{
if (i == 5)
break;
Console.WriteLine(i);
}
Console.ReadLine();


Console.WriteLine(
"for (int i = 1; i <= 10; i++) -> continue if i<9" );
for (int i = 1; i <= 10; i++)
{
if (i < 9)
continue;
Console.WriteLine(i);
}
Console.ReadLine();

}
}
}


موارد تكميلي مربوط به رد و بدل كردن مقادير به/از كلاس ها :

در قسمت بعدي مي خواهيم خاصيتي را تعريف كنيم كه يك مقدار را از كاربر مي گيرد و در برنامه مي توان توسط قسمت هاي ديگر از آن استفاده كرد.

ابتدا يك متغير عمومي بايد در سطح كلاس تعريف كرد تا مقدار دريافت شده توسط set را در خود نگاه داري كند (در مورد scope متغيرها ( متغيرهاي عمومي و محلي و امثال اينها) در هنگام معرفي توابع بيشتر بحث خواهد شد) . سپس از طريق كلمه ي كليدي value مقدار دريافت شده به متغير انتساب مي يابد و چون در سطح كلاس عمومي است در تمام كلاس قابل درسترسي است.

مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex12 انتخاب نماييد. سپس از منوي پروژه يك كلاس جديد به آن اضافه نماييد (به نام clsDate) و كد زير را درون آن بنويسيد :


using System;

namespace ex12
{
public class clsDate
{
private int Year;

public clsDate()
{
}

public int setYear
{
set
{
Year = value;
}
}

public bool IsLeapYear
{
get
{
return System.DateTime.IsLeapYear(Year);
}
}


}
}


براي استفاده از آن در متد main برنامه به صورت زير عمل مي كنيم:


using System;

namespace ex12
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
clsDate m_var = new clsDate();

m_var.setYear = 1990;

if (m_var.IsLeapYear)
Console.WriteLine("1990 is a leap year.");
else
Console.WriteLine("1990 is not a leap year.");

Console.ReadLine();
}
}
}


توضيحاتي در مورد كد فوق:

1- نحوه ي تعريف متغير از يك كلاس جزو اساسي ترين قسمت هاي كار با يك كلاس محسوب مي شود كه در قسمت هاي پيشين نيز معرفي گرديد.
2- هنگامي كه از if استفاده مي كنيم لزومي ندارد حتما بنويسيم m_var.IsLeapYear==true . همين كه اين خاصيت ذكر مي شود در وهله ي اول true بودن آن چك خواهد شد.
3- نحوه ي مقدار دهي به يك خاصيت را هم در كد فوق ملاحظه مي نماييد. در هنگام استفاده از خاصيت ها نيازي به آوردن پرانتزها () در مقابل نام آنها وجود ندارد.
4- براي مرور ، نحوه ي معرفي خاصيت ها با get نيز بيان گرديد. با استفاده از set و get مي توان به كلاس ها ، مقادير متغيرها را پاس كرد و يا مقداري را دريافت نمود.

WooKMaN
21-11-2005, 13:54
مقدمه اي بر سي شارپ : قسمت هفتم

تعريف متدها در سي شارپ

در اين قسمت به يكي از مهمترين مباحث برنامه نويسي سي شارپ مي رسيم.
متدها در سي شارپ و يا همان توابع در زبان C ، اعضاي يك شيء يا كلاس هستند و مجموعه اي از يك سري از كارها را انجام مي دهند. فرض كنيد در برنامه ي شما ، قسمتي بايد يك عمليات رياضي خاص را انجام دهد و اين قسمت از كد كه شامل چندين خط نيز مي گردد بايد بارها و بارها در برنامه صدا زده شود. براي نظم بخشيدن به برنامه ، آنها را مي توان به صورت توابع بسته بندي كرد و بجاي نوشتن چندين خط تكراري، فقط نام اين بسته ( تابع ) و پارامترهاي آن را فراخواني نمود.

در سي شارپ يك تابع به صورت زير تعريف مي شود :

(نوع و اسامي پارامترها) نام تابع نوع خروجي تابع سطح دسترسي به تابع
}
بدنه ي تابع
{

براي تعريف يك متد يا تابع ابتدا سطح دسترسي به آن مانند public و private سپس نوع خروجي تابع مانند void ( هيچي ) ذكر مي گردد كه داخل اين پرانتزها مي توان ورودي هاي تابع يا بقولي آرگومان هاي ورودي را معرفي كرد. سپس تابع بايد با { شروع و با يك } خاتمه يابد.

براي مثال :


public int myFunc( int x )
{
...….
}


هر تابعي مي تواند صفر تا تعداد بيشماري آرگومان ورودي و صفر تا تعداد بيشماري خروجي داشته باشد. بوسيله يك تابع مي توان پيچيدگي كار را مخفي كرد و صرفا با صدا زدن نام آن ، يك سري از عمليات را انجام داد. گاهي از اوقات لازم مي شود دو يا چند تابع با يك نام داشته باشيم بطوريكه پارامترهاي ورودي يا مقادير خروجي و يا نوع آرگومان هاي ورودي آنها با هم متفاوت باشد به اين كار overloading مي گويند.
بسياري از كلاس هاي دات نت فريم ورك متدها و يا توابع مفيد حاضر و آماده اي را دارند. براي مثال كلاس DateTime ، متدي به نام ToLongDatastring دارد كه تاريخ را به صورت يك رشته طولاني بر مي گرداند.

توابع void :

توابعي كه با نوع void معرفي مي شوند هيچ خروجي ندارند و در زبان ويژوال بيسيك به آْنها sub و در دلفي به آنها procedure مي گويند.

بازگرداندن يك مقدار از يك تابع :

پس از اينكه عمليات يك مجموعه از كدها درون تابع به پايان رسيد با استفاده از كلمه ي return مي توان خروجي تابع را معرفي كرد. لازم به ذكر است ، هرجايي اين كلمه ي return ذكر شود كار تابع خاتمه مي يابد.

بهتر است موارد فوق را با چند مثال مرور كنيم :

مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex13 انتخاب نماييد. در اينجا مي خواهيم تابعي را تعريف كنيم كه سه برابر جذر يك عدد را بر مي گرداند.


using System;

namespace ex13
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Console.WriteLine( int3SQL(3) );
Console.ReadLine();
}

public static double int3SQL( double intInput )
{
double i=0;
i = Math.Sqrt( intInput );
return i;
}
}
}


توضيحاتي در مورد كد فوق :

1- از شيء Math در سي شارپ مي توان براي انجام يك سري عمليات رياضي ابتدايي استفاده كرد. در اينجا از متد جذر گرفتن آن استفاده شده است.
2- در تعريف تابع خودمان از كلمه ي كليدي static استفاده شده است. درون تابع Main نمي توان توابع غير استاتيك را فراخواني كرد. فعلا اين نكته را بخاطر را داشته باشيد تا در مقالات بعدي بيشتر راجع به آن صحبت شود.
3- بد نيست تابع تعريف شده را كمي بيشتر آناليز كنيم :


public static double int3SQL( double intInput )
{
double i=0;
i = Math.Sqrt( intInput );
return i;
}


ابتدا سطح دسترسي به تابع ذكر شده است. پابليك ، يعني اين تابع خارج از كلاس يك برنامه نيز قابل دسترسي است. سپس از كلمه ي static استفاده گرديده كه توضيح مختصري را در مورد آن ملاحظه كرديد. در ادامه نوع خروجي تابع كه در اينجا double مي باشد معرفي گرديده است. دقت كنيد كه حتما بايد نوع تعريف شده با مقداري كه يك تابع بر مي گرداند يكسان باشد و گرنه با يك خطا برنامه متوقف مي شود. سپس نام تابع تعريف شده است. داخل پرانتز ها نوع و نام آرگوماني ارائه شده است كه در بدنه ي تابع استفاده مي گردد. اگر به تعداد بيشتري پارامتر و يا آرگومان نياز بود مي توان آنها را با , از هم جدا كرد.
پس از اينكه عمليات تابع خاتمه مي يابد با استفاده از return اين خروجي را معرفي مي نماييم.
براي استفاده از اين تابع به سادگي نام تابع و سپس پرانتزها به همراه يك عدد دلخواه را مي نويسم كه آنرا در متد Main برنامه مي توان مشاهده كرد.

تعريف توابع در كلاس هاي ديگر برنامه و نحوه ي استفاده از آنها :

يكي از زيبايي هاي برنامه نويسي شيء گرا نظم و ترتيب و بسته بندي كارها مي باشد كه اصطلاحا در اينجا به آن encapsulation مي گويند. يعني ما يك سري از توابع و خواص را درون كپسولي به نام كلاس قرار مي دهيم تا به سادگي بارها و بارها از آن استفاده نماييم.
براي اينكار به سادگي يك توابع را به صورت معمول درون كلاس تعريف مي نماييم و سپس همانند خواص كه در مورد آنها صحبت شد ، از توابع مي توان استفاده كرد با اين تفاوت كه هنگام كار با توابع حتي اگر آنها هيچ آرگومان و يا پارامتر ورودي هم نداشته باشند ذكر پرانتزها الزامي است.

مثالي ديگر در اين زمينه :

مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex14 انتخاب نماييد. سپس از منوي پروژه يك كلاس جديد را به برنامه اضافه نماييد (نام آنرا clsTools بگذاريد) .


using System;

namespace ex14
{
public class clsTools
{
public clsTools()
{
}

public uint intCalc ( uint a , uint b )
{
uint c = Math.Min (a,b);
double x = Math.Sqrt(c) ;
uint w = Convert.ToUInt32 ( x);
return w;
}
}
}


سپس در متد Main برنامه مي توان به صورت زير از آن استفاده كرد :


using System;

namespace ex14
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
clsTools m_var = new clsTools();
Console.WriteLine( m_var.intCalc(4,9));
Console.ReadLine();
}
}
}


توضيحاتي در مورد كد فوق :
1- تابع intCalc ما دو عدد صحيح مثبت را مي گيرد و سپس جذر كوچكترين دو عدد ورودي را محاسبه مي كند.
2- براي تبديل نوع هاي عددي مختلف به هم مي توان از شيء Convert استفاده كرد.
3- بدون استفاده از شيء Convert يكبار برنامه را اجرا كنيد و دليل خطاي بوجود آمده را بيان نماييد

WooKMaN
21-11-2005, 13:55
مقدمه اي بر سي شارپ : قسمت هشتم

چگونه از يك تابع بيش از يك خروجي دريافت كنيم.

ظاهرا به نظر مي رسد كه توابع فقط مي توانند يك return داشته باشند و بلافاصله پس از فراخواني return كار تابع پايان يافته است. در سي شارپ دو كلمه ي كليدي به نام هاي ref و out اضافه شده اند كه اين امر را ساده تر مي كنند.

استفاده از كلمه ي كليدي out :

از out در تعريف تابع قبل از معرفي نوع آرگومان ورودي استفاده مي كنيم . در اين حالت بجاي اينكه به اين آرگومان ، آرگومان ورودي بگوييم ، مي توان آنرا آرگومان خروجي ناميد. تا يك مثال را در اين زمينه با هم مرور نكنيم اين مورد مفهوم نخواهد بود :

مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex15 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


using System;

namespace ex15
{
class Class1
{

public static int TestOut(out char i)
{
i = 'b';
return -1;
}

[STAThread]
static void Main(string[] args)
{
char i; // variable need not be initialized
Console.WriteLine(TestOut(out i));
Console.WriteLine(i);
Console.ReadLine();

}
}
}


توضيحاتي در مورد كد فوق :
1- در تابع TestOut آرگومان i از با كلمه ي كليدي out مشخص شده است. يعني اينكه درون تابع هر گونه تغييري روي i انجام شود ، خارج از تابع قابل دسترسي است.
2- توابعي كه داراي آرگومانهايي تعريف شده با كلمه ي كليدي out هستند نيز مي توانند از return هم استفاده كنند. همانند مثال فوق.

استفاده از كلمه ي كليدي ref :

اين كلمه ي كليدي نيز دقيقا همانند out عمل مي كند و نحوه ي تعريف و استفاده از آن نيز مشابه است با اين تفاوت كه آرگوماني كه به اين نوع توابع فرستاده مي شود بايد مقدار دهي اوليه شده باشد.

مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex16 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


using System;

namespace ex16
{
class Class1
{
public static void FillArray(ref int[] arr)
{
// Create the array on demand:
if (arr == null)
arr = new int[10];
// Otherwise fill the array:
arr[0] = 123;
arr[4] = 1024;
}

[STAThread]
static void Main(string[] args)
{
// Initialize the array:
int[] myArray = {1,2,3,4,5};

// Pass the array using ref:
FillArray(ref myArray);

// Display the updated array:
Console.WriteLine("Array elements are:");
for (int i = 0; i < myArray.Length; i++)
Console.WriteLine(myArray[i]);

Console.ReadLine();
}
}
}


توضيحاتي در مورد كد فوق :
1- همانطور كه ملاحظه مي كنيد در اينجا هنگام استفاده از تابع FillArray بايد آرگوماني را كه مي خواهيم به آن پاس كنيم مقدار دهي اوليه كنيم.
2- پس مي توان نتيجه گرفت آرگومانهايي كه با out تعريف مي شوند به صورت خالص خروجي هستند و نيازي به مقدار دهي اوليه هنگام استفاده از آنها وجود ندارد. از ref هنگامي استفاده مي كنيم كه بخواهيم روي متغير موجود و مقدار دهي شده ي خارج از تابع ، درون تابع عملياتي صورت گيرد و سپس همان متغير دستكاري شده ، عودت داده شود.

تعريف تابعي با تعداد آرگومانهاي نامعلوم :

گاهي از اوقات نياز است تا تابعي تعريف كنيم كه تعداد آرگومانهاي آن متغير باشند .براي اين منظور از كلمه ي كليدي params استفاده مي شود.
دونكته در اينجا حائز اهميت است:
1- در هر تابعي تنها مي توان يكبار از params استفاده كرد.
2- پس از بكار بردن params ديگر نمي توان هيچ آرگوماني را تعريف كرد.

يكي از مثالهايي كه در اين زمينه مي توان ارائه داد استفاده از آرايه ها به عنوان آرگومان ورودي است. در اين حالت يا مي توان يك آرايه را به صورت كامل به تابع معرفي كرد و يا تنها نام آنرا به تابع پاس كرد. مثال زير را ملاحظه كنيد :

مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex17 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


using System;

namespace ex17
{
class Class1
{
public static void UseParams(params int[] list)
{
for ( int i = 0 ; i < list.Length ; i++ )
Console.WriteLine(list[i]);
Console.WriteLine();
}

[STAThread]
static void Main(string[] args)
{
UseParams(1, 2, 3);

int[] myarray = new int[3] {10,11,12};
UseParams(myarray);

Console.ReadLine();

}
}
}


توضيحاتي در مورد كد فوق :

1- در تابع main به دو صورت از تابع UseParams ما استفاده شده است. يا اينكه خيلي ساده هر تعداد آرگومان را مي توان به تابع فرستاد و يا اينكه در ادامه آرايه ايي رسما تعريف و سپس به تابع فرستاده شود.
2- نحوه ي تعريف و استفاده از آرايه ها به صورت آرگومان ورودي را نيز مي توان در مثال فوق آموخت

WooKMaN
21-11-2005, 13:57
مقدمه اي بر سي شارپ : قسمت نهم

مبحث overloading :

گاهي از اوقات لازم است تا نگارش هاي مختلفي از يك تابع داشته باشيم. براي مثال تعريف سه تابع با يك نام اما با آرگومانهاي مختلف. به اين نوع توابع و يا متدها اصطلاحا Overloaded Methods مي گويند . ( فكر كنم آنرا سربارگذاري توابع ترجمه كرده اند! ) براي مثال :


void myMethod(int p1);
void myMethod(int p1, int p2);
void myMethod(int p1, string s1);


مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex18 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


using System;

namespace ex18
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
writeIT();

writeIT(12);

Console.ReadLine();
}

public static void writeIT()
{
Console.WriteLine(" writeIT() Ver." );
}

public static void writeIT(int intI)
{
Console.WriteLine(" writeIT(intI) Ver. = " + intI );
}


}
}


توضيحاتي در مورد كد فوق :

1- نحوه ي تعريف دو تابع با يك نام را ملاحظه مي نماييد. اينكار در زبان سي ممنوع است!
2- كامپايلر به صورت هوشمند بر اساس نوع و تعداد آرگومانهاي ورودي ، ورژن مناسب را انتخاب و اجرا مي كند.

نمونه ي ضعيفي از اين بحث در وي بي 6 به صورت تعريف توابعي با پارامترهاي Optional وجود داشت .

مباحث تكميلي آرايه ها (آرايه هاي چند بعدي):

آرايه هاي معمولي (يك بعدي) را مي توان يك رديف با تعدادي خانه خالي آماده ي پر شدن در نظر گرفت. آرايه ي دوبعدي را مي توان مانند يك جدول تشكليل شده از رديف ها و ستون ها در نظر گرفت و الي آخر...
سي شارپ دو نوع آرايه ي چند بعدي را پشتيباني مي كند : rectangular and jagged
در يك آرايه ي rectangular هر رديف ، طولش با رديف بعدي يكي است. آرايه ي jagged در حقيقت آرايه ايي از آرايه ها است ، بنابراين هر كدام از آنها مي تواند طول مختلفي داشته باشد.

تعريف يك آرايه ي دوبعدي به صورت زير است :


type [,] array-name


مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex19 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


using System;

namespace ex19
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
const int rows = 4;
const int columns = 3;
// declare a 4x3 integer array
int[,] rectangularArray = new int[rows, columns];
// populate the array
for (int i = 0;i < rows;i++)
{
for (int j = 0;j {
rectangularArray[i,j] = i+j;
}
}
// report the contents of the array
for (int i = 0;i < rows;i++)
{
for (int j = 0;j {
Console.WriteLine("rectangularArray[{0},{1}] = {2}",
i,j,rectangularArray[i,j]);
}
}

Console.ReadLine();
}
}
}


توضيحاتي در مورد كد فوق :
1- نحوه ي تعريف ، مقدار دهي اوليه و استفاده از آرايه هاي دو بعدي را در مثال فوق ملاحظه مي نماييد.
2- در يك آرايه ي دوبعدي محل قرار گيري رديف ها و ستون ها براي مثال به صورت زير است :


new int[rows, columns]-


استفاده از آرايه هاي چند بعدي :

مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex20 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


using System;

namespace ex20
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
const int rows = 4;
const int columns = 3;
// imply a 4x3 array
int[,] rectangularArray =
{
{0,1,2},
{3,4,5},
{6,7,8},
{9,10,11}
};
for (int i = 0;i < rows;i++)
{
for (int j = 0;j {
Console.WriteLine("rectangularArray[{0},{1}] = {2}",
i,j,rectangularArray[i,j]);
}
}
}
}
}


توضيحاتي در مورد كد فوق :
1- در حقيقت مثال فوق تعريف آرايه ايي از آرايه ها بود.
2- چون مقدار دهي اوليه به صورت واضحي انجام شده نيازي به ذكر ابعاد آرايه به صورت صحيح وجود نداشت

WooKMaN
21-11-2005, 13:58
مقدمه اي بر سي شارپ : قسمت دهم

Jagged arrays

Jagged arrays آرايه اي از آرايه ها است و همانطور كه ذكر شد لزومي ندارد كه هر رديف آن با رديف بعدي هم طول باشد . هنگام تعريف اين نوع آرايه شما تعداد رديف ها را مشخص مي نماييد. هر رديف يك آرايه را نگهداري مي كند. در اينجا هر آرايه بايد تعريف شود. روش تعريف Jagged array به صورت زير است

type [] []...


در اينجا تعداد براكت ها بيانگر ابعاد آرايه مي باشد. براي مثال آرايه ي زير دو بعدي است :


int [] [] myJaggedArray;


و براي مثال براي دسترسي به پنجمين عنصر آرايه ي سوم به صورت زير عمل مي شود :


myJaggedArray[2][4]


مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex21 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


using System;

namespace ex21
{
class Class1
{
[STAThread]
static void Main(string[] args)
{

const int rows = 4;
// declare the jagged array as 4 rows high
int[][] jaggedArray = new int[rows][];
// the first row has 5 elements
jaggedArray[0] = new int[5];
// a row with 2 elements
jaggedArray[1] = new int[2];
// a row with 3 elements
jaggedArray[2] = new int[3];
// the last row has 5 elements
jaggedArray[3] = new int[5];
// Fill some (but not all) elements of the rows
jaggedArray[0][3] = 15;
jaggedArray[1][1] = 12;
jaggedArray[2][1] = 9;
jaggedArray[2][2] = 99;
jaggedArray[3][0] = 10;
jaggedArray[3][1] = 11;
jaggedArray[3][2] = 12;
jaggedArray[3][3] = 13;
jaggedArray[3][4] = 14;
for (int i = 0;i < 5; i++)
{
Console.WriteLine("jaggedArray[0][{0}] = {1}",
i,jaggedArray[0][i]);
}
for (int i = 0;i < 2; i++)
{
Console.WriteLine("jaggedArray[1][{0}] = {1}",
i,jaggedArray[1][i]);
}
for (int i = 0;i < 3; i++)
{
Console.WriteLine("jaggedArray[2][{0}] = {1}",
i,jaggedArray[2][i]);
}
for (int i = 0;i < 5; i++)
{
Console.WriteLine("jaggedArray[3][{0}] = {1}",
i,jaggedArray[3][i]);
}

Console.ReadLine();

}
}
}


توضيحاتي در مورد كد فوق :

هنگام كار با آرايه هاي rectangular براي درسترسي به اعضا به صورت زير عمل مي شد :


rectangularArrayrectangularArray[i,j]


اما در اينجا بدين صورت است :


jaggedArray[3][i]


استفاده از System.Array :

دات نت فريم ورك كلاسي را معرفي كرده است به نام Array. توسط اين كلاس كار با آرايه ها و اعمال روي آنها براي مثال سورت كردن و غيره به شدت ساده مي شود .


مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex22 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


using System;

namespace ex22
{
class Class1
{
public static void PrintMyArray(object[] theArray)
{
foreach (object obj in theArray)
{
Console.WriteLine("Value: {0}", obj);
}
Console.WriteLine("\n");
}

[STAThread]
static void Main(string[] args)
{
String[] myArray = {
"Who", "is", "John", "Galt"
};
PrintMyArray(myArray);
Array.Reverse(myArray);
PrintMyArray(myArray);
String[] myOtherArray = {
"We", "Hold", "These", "Truths",
"To", "Be", "Self", "Evident" };

PrintMyArray(myOtherArray);
Array.Sort(myOtherArray);
PrintMyArray(myOtherArray);

Console.ReadLine() ;

}
}
}


توضيحاتي در مورد كد فوق :
از دو متد Sort و Reverse در اينجا براي سورت كردن و نمايش آرايه به ترتيب معكوس (از انتها به ابتدا) استفاده گرديده است.

تعريف آرايه هاي ديناميك در سي شارپ :

يكي از مشكلاتي كه با آرايه هاي معمول وجود دارد اين است كه قبل از هر كاري بايد طول آْنها را مشخص كرد. گاهي از اوقات ما دقيقا نمي دانيم برنامه چه تعداد عضو را دريافت مي كند تا آرايه اي از پيش تعريف شده با همان تعداد عضو ايجاد كنيم. براي حل اين مشكل از كلاس ArrayList تعريف شده در دات نت فريم ورك مي توان استفاده كرد.

هنگام استفاده از ArrayList نيازي به دانستن تعداد اعضايي كه بايد اضافه شوند نمي باشد و با استفاده از متد Add آن به سادگي مي توان اعضاء را به آن اضافه نمود . تعدادي از خواص و متدهاي اين كلاس به صورت زير هستند :

Adapter , FixedSize , ReadOnly , Repeat , Synchronized , Capacity,Count , IsFixedSize , IsReadOnly , IsSynchronized , Item , SyncRoot , Add , AddRange , BinarySearch , Clear , Clone , Contains , CopyTo , GetEnumerator , GetRange , IndexOf , Insert , InsertRange , LastIndexOf , Remove , RemoveAt , RemoveRange , Reverse , SetRange , Sort , ToArray , TrimToSize

مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex23 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


using System;
using System.Collections;

namespace ex23
{
// a simple class to store in the array
public class Employee
{
public Employee(int empID)
{
this.empID = empID;
}
public override string ToString( )
{
return empID.ToString( );
}
public int EmpID
{
get
{
return empID;
}
set
{
empID = value;
}
}
private int empID;
}

class Class1
{
[STAThread]
static void Main(string[] args)
{

ArrayList empArray = new ArrayList( );
ArrayList intArray = new ArrayList( );
// populate the array
for (int i = 0;i<5;i++)
{
empArray.Add(new Employee(i+100));
intArray.Add(i*5);
}
// print all the contents
for (int i = 0;i {
Console.Write("{0} ", intArray[i].ToString( ));
}
Console.WriteLine("\n");
// print all the contents of the button array
for (int i = 0;i {
Console.Write("{0} ", empArray[i].ToString( ));
}
Console.WriteLine("\n");
Console.WriteLine("empArray.Capacity: {0}",
empArray.Capacity);

Console.ReadLine();

}
}
}


توضيحاتي در مورد كد فوق :

1- با كلمه ي كليدي override در قسمت هاي بعدي آشنا خواهيم شد.
2- براي استفاده از ArrayList لازم بود تا فضاي نامي را كه اين كلاس در آن تعريف شده است ، به برنامه اضافه كرد.
3- در مثال فوق نحوه ي تعريف دو كلاس را در يك فضاي نام مشاهده مي نماييد.
4- نحوه ي تعريف و مقدار دهي ArrayList و همچنين استفاده از خواص آن در مثال فوق بررسي شده است

WooKMaN
21-11-2005, 13:59
مقدمه اي بر سي شارپ : قسمت يازدهم

از اين قسمت به بعد مي خواهيم نگاهي دقيق تر به بحث شيء گرايي در سي شارپ بياندازيم؛ همانند فضاهاي نام ، كلاس ها ، ارث بري ، پلي مرفيسم و غيره.

در قسمت هاي قبل آشنايي مختصري با فضاهاي نام پيدا كرديم. در ادامه جزئيات بيشتري را در مورد آن بررسي خواهيم كرد.
فضاهاي نام (namespaces) براي اداره كردن و نظم بخشيدن به كدها ارائه شده اند. همچنين از امكان تشابه اسمي در بين قسمت هاي مختلف برنامه نيز جلوگيري مي كنند. استفاده از آنها عادت پسنديده اي است هنگاميكه قصد داريم از كد نوشته شده بارها و بارها استفاده كنيم.

مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex24 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


// Namespace Declaration
using System;

namespace ex24
{
namespace tutorial
{
// Program start class
class NamespaceCSS
{
// Main begins program execution.
public static void Main()
{
// Write to console
Console.WriteLine("This is the new Namespace.");
}
}
}

}


توضيحاتي در مورد كد فوق :
يكي از روش هاي مناسب براي معرفي فضاهاي نام ، ارائه ي آنها به صورت سلسله مراتبي مي باشد. قسمت هاي عمومي تر در بالا و قسمت هاي اختصاصي تر در فصاهاي نام داخلي تر قرار داده مي شوند. اين روش به معرفي فضاهاي نام تو در تو منتهي مي شود (nested namespaces) ، همانند مثال بالا.

كد فوق را به صورت زير با استفاده از عملگر دات (.) مي توان خلاصه نويسي كرد و نتيجه با قبل تفاوتي ندارد:


// Namespace Declaration
using System;

namespace ex24.tutorial
{
// Program start class
class NamespaceCSS
{
// Main begins program execution.
public static void Main()
{
// Write to console
Console.WriteLine("This is the new Namespace.");
}
}
}


طريقه ي فراخواني اعضاي فضاهاي نام :

مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex25 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


// Namespace Declaration
using System;

namespace ex25
{
// nested namespace
namespace tutorial
{
class myExample1
{
public static void myPrint1()
{
Console.WriteLine("calling another namespace member1.");
}
}
}

// Program start class
class NamespaceCalling
{
// Main begins program execution.
public static void Main()
{
// Write to console
tutorial.myExample1.myPrint1();
tutorial.myExample2.myPrint2();
}
}
}

// same namespace as nested namespace above
namespace ex25.tutorial
{
class myExample2
{
public static void myPrint2()
{
Console.WriteLine("calling another namespace member2.");
}
}
}


توضيحاتي در مورد كد فوق :
در كد فوق نحوه ي استفاده از اعضاي تعريف شده در فضاهاي نام را مي توان مشاهده كرد. نحوه ي استفاده از آنها همانطور كه در قسمت هاي قبل نيز گفته شد به صورت زير است :


ProjectName.NameSpace.ClassName.MemberName


براي مثال در فصاي نام tutorial كلاس myExample1 قرار دارد و داخل آن متد myPrint1 تعريف شده است. پس نحوه ي دسترسي به متد آن به صورت زير است :


tutorial.myExample1.myPrint1();


كلاس هاي myExample1 و myExample2 هر دو به يك فضاي نام (ex25.tutorial) تعلق دارند ، هر چند جدا از هم نوشته شده اند. حتي آنها را با حفظ سلسله مراتب خودشان مي توان در فايلهاي جداگانه اي نيز نوشت.

استفاده از using :

مثال : يك برنامه ي سي شارپ جديد console را در VS.NET باز كنيد و نام آنرا درابتدا ex26 انتخاب نماييد. سپس كد زير را درون آن بنويسيد :


// Namespace Declaration
using System;
using ex26.tutorial;

// Program start class
class UsingDirective
{
// Main begins program execution.
public static void Main()
{
// Call namespace member
myExample.myPrint();
}
}

// C# Namespace
namespace ex26.tutorial
{
class myExample
{
public static void myPrint()
{
Console.WriteLine("Example of using a using directive.");
}
}
}


توضيحاتي در مورد كد فوق :

همانند مثال بالا ، براي خلاصه نويسي مي توان از كلمه ي using به همراه نام namespace مورد نظر استفاده كرد. براي مثال اگر متد WriteLine را بخواهيم كامل بنويسيم به صورت زير است :


System.Console.WriteLine(...);


اما با قيد كردن و الحاق كردن فضاي نام آن ، ديگر نيازي به ذكر System در ابتداي آن نيست.

نكته :

باز هم مي توان خلاصه نويسي بيشتري را ارائه داد


using csTut = ex26.tutorial.myExample; // alias


در اين صورت تنها كافي است متد كلاس تعريف شده در آنرا به صورت زير فراخواني كنيم :


csTut.myPrint();

WooKMaN
21-11-2005, 14:00
مقدمه اي بر سي شارپ : قسمت دوازدهم


كلاس ها در سي شارپ :

تا بحال در حد كاربرد ، با كلاس ها آشنا شده ايم . اما در اين قسمت مي خواهيم نگاهي دقيق تر به كلاس ها بياندازيم.

هر كدي در سي شارپ قسمتي از يك كلاس مي باشد و تركيب تمام خواص و متدهاي موجود در يك كلاس يك نوع داده ي جديد تعريف شده از طرف ما را پديد مي آورد. هر متغيري كه از كلاس ساخته شود ، شيء ناميده مي شود و يك كپي منحصر به فرد است. براي مثال برنامه ي زير را درنظر بگيريد :


using System;

class Data
{
public int x;
}
class App
{
public static void Main()
{
Data d1 = new Data();
d1.x = 1;
Data d2 = new Data();
d2.x = 2;
Console.WriteLine("d1.x = {0}", d1.x);
Console.WriteLine("d2.x = {0}", d2.x);
}
}


در اينجا كلاس Data تعريف شده است و داراي يك عضو به نام x مي باشد. به اين نوع داده در كلاس فيلد گفته مي شود و هنگاميكه به صورت public معرفي مي شود يعني خارج از كلاس نيز قابل دسترسي است. در كد بالا دو متغير از كلاس تعريف و مقدار دهي اوليه شده اند. خروجي برنامه به صورت زير است :


d1.x = 1
d2.x = 2


دليل اين خروجي آن است كه هر instance (نمونه) از كلاس منحصر بفرد است و در اينجا نمي توان انتظار داشت كه هر دو خروجي يكي شوند.

براي مقدار دهي اوليه متغيرهايي كه به صورت فيلد تعريف مي شوند ، بهتر است مقدار دهي آنها را در سازنده ي كلاس (constructor) انجام دهيم.


class Data
{
public int x;
public Data(){x = 99;}
}


همانطور كه پيشتر نيز ذكر شد ، متدي كه هم نام كلاس است ، سازنده نام مي گيرد. يك كلاس مي تواند بيش از يك سازنده داشته باشد. براي مثال :


class Data
{
public int x;
private Data(){}
public Data(int y){x = y;}
public Data(int y, int z){x = y + z;}
}


از آنجائيكه كه سازنده ي بدون پارامتر ذكر شده در كد فوق private تعريف شده است بنابراين خارج از كلاس ديگر قابل دسترسي نمي باشد . بنابراين كدي خارج از كلاس ، تنها مي تواند از دو سازنده ي ديگر استفاده كند. براي مثال تعريف دو متغير جديد از اين كلاس به صورت زير مي باشد :


Data d1 = new Data(44);
Data d2 = new Data(22, 33);


سي شارپ به شما اجازه مي دهد تا سازنده ها را در يك كلاس توسط كلمه ي كليدي this نيز فراخواني كنيد يعني بجاي ذكر نام متد سازنده از كلمه ي this استفاده شود ( در خود كلاس ) .

اگر مي خواهيد متغيري را بين نمونه (instance) هاي مختلف يك كلاس به اشتراك بگذاريد كلمه ي كليدي static وارد صحنه مي شود. به مثال زير توجه كنيد :


using System;

class Counted
{
public static int count = 0;
public Counted()
{
count++;
}
public int GetInstanceCount()
{
return count;
}
}
class App
{
public static void Main()
{
Counted d1 = new Counted();
Console.WriteLine("current total {0}", d1.GetInstanceCount());
Counted d2 = new Counted();
Console.WriteLine("current total {0}", d2.GetInstanceCount());
Console.WriteLine("total {0}", Counted.count);
}
}


بايد خاطر نشان كرد كه متغيرهاي استاتيك توسط نمونه هاي كلاس قابل دستيابي نيستند و فقط درون كلاس به شكل زير مي توان از آْنها استفاده كرد :


.


در مثال فوق دو نمونه از كلاس Counted تعريف شده است. با هر بار فراخواني كلاس ، خودبخود سازنده اجرا شده و يك عدد به اين شمارشگر استاتيك اضافه مي شود. همانطور كه ذكر شد، براي اينكه بتوان به اين متغير استاتيك در خارج از كد دسترسي پيدا كرد يك متد غير استاتيك تعريف شده است.

در مثال فوق تابع GetInstanceCount تنها يك عدد را بر مي گرداند. در برنامه نويسي شيء گرا مرسوم است كه در اين حالت به جاي توابع از خواص استفاده شود كه به اندازه ي كافي در مورد آنها در قسمت هاي قبل توضيح داده شد. در اين صورت تعريف فوق به صورت زير در مي آيد :


class Counted
{
public static int x = 0;
public Counted()
{
x++;
}
public int InstanceCount // property
{
get{return x;}
}
}


و در اين صورت قسمت بعدي كد به صورت زير اصلاح مي شود (فراخواني خواص ، بدون ذكر پرانتزها بعد از نام آنها صورت مي گيرد):


Counted d1 = new Counted();
Console.WriteLine("current total {0}", d1.InstanceCount);
Counted d2 = new Counted();
Console.WriteLine("current total {0}", d2.InstanceCount);


اگر يك خاصيت هم خواندني و هم نوشتني باشد به صورت زير تعريف مي شود :


private string name;
public string Name
{
get{return name;}
set{name = value;}
}


فيلدهاي پابليك را مي توان خواند و يا تغيير داد. اگر لازم باشد تا كاربر نتواند آنها را تغيير دهد مي توان از كلمه ي كليدي readonly قبل از تعريف آنها استفاده كرد. مثال :


class Data
{
public readonly int x = 42;
}


بحث كلاس ها ادامه دارد...

WooKMaN
21-11-2005, 14:01
مقدمه اي بر سي شارپ : قسمت سيزدهم


ايندكسرها (Indexers)

با استفاده از ايندكسرها مي توان با يك كلاس همانند آرايه ها رفتار كرد. به مثال زير توجه كنيد :


using System;

///
/// A simple indexer example.
///
class IntIndexer
{
private string[] myData;

public IntIndexer(int size)
{
myData = new string[size];

for (int i=0; i < size; i++)
{
myData[i] = "empty";
}
}

public string this[int pos]
{
get
{
return myData[pos];
}
set
{
myData[pos] = value;
}
}

static void Main(string[] args)
{
int size = 10;

IntIndexer myInd = new IntIndexer(size);

myInd[9] = "Some Value";
myInd[3] = "Another Value";
myInd[5] = "Any Value";

Console.WriteLine("\nIndexer Output\n");

for (int i=0; i < size; i++)
{
Console.WriteLine("myInd[{0}]: {1}", i, myInd[i]);
}
}
}


در مثال فوق نحوه ي تعريف و استفاده از ايندكسرها را مي توان مشاهده كرد. كلاس IntIndexer حاوي آرايه اي به نام myData مي باشد. بدليل private بودن آن در خارج از كلاس قابل دسترسي نيست. اين آرايه در سازنده ي كلاس (متد IntIndexer) با كلمه ي empty مقدار دهي اوليه شده است.
عضو بعدي كلاس Indexer مي باشد و با كلمه ي كليدي this و براكتها مشخص شده ست (this[int pos]). همانطور كه ملاحظه مي فرماييد نحوه ي تعريف ايندكسرها شبيه به تعريف خواص مي باشد.


this [argument list]
{
get
{
// Get codes goes here
}
set
{
// Set codes goes here
}
}


خروجي مثال فوق به صورت زير است :


myInd[0]: empty
myInd[1]: empty
myInd[2]: empty
myInd[3]: Another Value
myInd[4]: empty
myInd[5]: Any Value
myInd[6]: empty
myInd[7]: empty
myInd[8]: empty
myInd[9]: Some Value


استفاده از اعداد صحيح روشي است متداول براي دسترسي به اعضاي آرايه ها در بسياري از زبانها اما ايندكسرها در سي شارپ فراتر از اين مي رود. ايندكسرها را مي توان با پارامترهاي متعددي تعريف كرد و هر پارامتر با نوعي مختلف (دقيقا همانند پارامترهاي ورودي متدها). البته محدوديتي كه اينجا وجود دارد در مورد نوع پارامتر ها است كه تنها مي تواند integers, enums, and strings باشد . بعلاوه قابليت Overloading ايندكسرها نيز وجود دارد. به همين جهت به آنها آرايه هاي هوشمند هم گفته مي شود (smart arrays) .مثال :


using System;

///
/// Implements overloaded indexers.
///
class OvrIndexer
{
private string[] myData;
private int arrSize;

public OvrIndexer(int size)
{
arrSize = size;
myData = new string[size];

for (int i=0; i < size; i++)
{
myData[i] = "empty";
}
}

public string this[int pos]
{
get
{
return myData[pos];
}
set
{
myData[pos] = value;
}
}

public string this[string data]
{
get
{
int count = 0;

for (int i=0; i < arrSize; i++)
{
if (myData[i] == data)
{
count++;
}
}
return count.ToString();
}
set
{
for (int i=0; i < arrSize; i++)
{
if (myData[i] == data)
{
myData[i] = value;
}
}
}
}

static void Main(string[] args)
{
int size = 10;
OvrIndexer myInd = new OvrIndexer(size);

myInd[9] = "Some Value";
myInd[3] = "Another Value";
myInd[5] = "Any Value";

myInd["empty"] = "no value";

Console.WriteLine("\nIndexer Output\n");

for (int i=0; i < size; i++)
{
Console.WriteLine("myInd[{0}]: {1}", i, myInd[i]);
}

Console.WriteLine("\nNumber of \"no value\" entries: {0}", myInd["no value"]);
}
}


در مثال فوق اولين ايندكسر با يك پارامتر از نوع اعداد صحيح تعريف شده است و در ايندكسر دوم از نوع رشته.
خروجي برنامه ي فوق به صورت زير است :


myInd[0]: no value
myInd[1]: no value
myInd[2]: no value
myInd[3]: Another Value
myInd[4]: no value
myInd[5]: Any Value
myInd[6]: no value
myInd[7]: no value
myInd[8]: no value
myInd[9]: Some Value

Number of "no value" entries: 7


نكته :
1- امضاي (ليست پارامترهاي) ايندكسر ها در يك كلاس بايد منحصر بفرد باشد .
2- تعريف يك ايندكسر به صورت استاتيك مجاز نيست.

در صورت نياز به ايندكسرهايي با پارمترهاي ورودي متعدد مي توان به صورت زير عمل كرد :


public object this[int param1, ..., int paramN]
{
get
{
// process and return some class data
}
set
{
// process and assign some class data
}
}


يك مثال ديگر :


using System;

class IndexExample
{
string Message;

public static void Main()
{
IndexExample obj=new IndexExample("Welcome");

/* This will access the String variable Message
using array like notation
*/
for(int i=0;i < obj.Length;i++)
{
Console.WriteLine(obj[i]);
}
obj[obj.Length-1]="e to C#";

Console.WriteLine(obj.Message);

}

public IndexExample(string s)
{
Message=s;
}

public string this[int i]
{
get
{
if(i >= 0 && i < Message.Length)
{
return Message.Substring(i,1);
}
else
{
return "";
}
}
set
{
if(i >= 0 && i < Message.Length)
{
Message=Message.Substring(0,i) + value + Message.Substring(i+1);
}
}
}

public int Length
{
get
{
if(Message!=null)
{
return Message.Length;
}
else
return 0;
}
}
}

WooKMaN
21-11-2005, 14:02
مقدمه اي بر سي شارپ : قسمت چهاردهم


ارث بري (Inheritance) :

ارث بري يكي از مفاهيم اوليه ي برنامه نويسي شيء گرا مي باشد. با استفاده از آن استفاده مجدد از كد موجود به نحوي مؤثر ميسر مي گردد و صرفه جويي قابل توجهي را در زمان برنامه نويسي پديد مي آورد. به كد زير دقت كنيد :


using System;

public class ParentClass
{
public ParentClass()
{
Console.WriteLine("Parent Constructor.");
}
public void print()
{
Console.WriteLine("I'm a Parent Class.");
}
}

public class ChildClass : ParentClass
{
public ChildClass()
{
Console.WriteLine("Child Constructor.");
}
public static void Main()
{
ChildClass child = new ChildClass();
child.print();
}
}

Output:
Parent Constructor.
Child Constructor.
I'm a Parent Class.


كد فوق از دو كلاس استفاده مي كند. كلاس بالايي ParentClass و كلاس اصلي ChildClass مي باشد. كاري كه انجام شده است استفاده از كدهاي كلاس والد ParentClass در كلاس بچه (!) ChildClass مي باشد. براي اينكه ParentClass را بعنوان كلاس پايه براي ChildClass معرفي كنيم به صورت زير عمل شد :


public class ChildClass : ParentClass


كلاس پايه با استفاده از معرفي كولون ":" ، پس از كلاس مشتق شده تعريف مي شود. در سي شارپ تنها ارث بري يگانه پشتيباني مي شود. بنابراين تنها يك كلاس پايه را براي ارث بري مي توان تعريف كرد.

ChildClass دقيقا توانايي هاي ParentClass را دارا است. بنابراين مي توان گفت ChildClass همان ParentClass است. براي مثال در كد فوق ChildClass داراي متد print نمي باشد اما آنرا از كلاس ParentClass به ارث برده است و در متد Main برنامه از آن استفاده گرديده است.

هنگام ساختن يك شيء از كلاس مشتق شده (derived) ، ابتدا يك نمونه از كلاس والد خود بخود ساخته مي شود. اين مورد در خروجي كد فوق هنگامي كه متدهاي سازنده ها روي صفحه چاپ شده اند قابل مشاهده است.

تبادل اطلاعات بين كلاس والد و كلاس فرزند :

به مثال زير دقت كنيد :


using System;

public class Parent
{
string parentString;

public Parent()
{
Console.WriteLine("Parent Constructor.");
}

public Parent(string myString)
{
parentString = myString;
Console.WriteLine(parentString);
}

public void print()
{
Console.WriteLine("I'm a Parent Class.");
}
}

public class Child : Parent
{
public Child() : base("From Derived")
{
Console.WriteLine("Child Constructor.");
}

public void print()
{
base.print();
Console.WriteLine("I'm a Child Class.");
}

public static void Main()
{
Child child = new Child();
child.print();
((Parent)child).print();
}
}

Output:
From Derived
Child Constructor.
I'm a Parent Class.
I'm a Child Class.
I'm a Parent Class.


كلاس فرزند با كلاس والد در هنگام instantiation مي تواند تبادل اطلاعات كند. همانطور كه در مثال فوق بارز است با استفاده از كلمه ي كليدي base ، كلاس فرزند تابع سازنده ي كلاس والد را فراخواني كرده است. اولين خط خروجي بيانگر اين موضوع است.

گاهي از اوقات ما مي خواهيم تابعي را كه در كلاس والد تعريف شده است را در كلاس فرزند با تعريف ديگري و مخصوص به خودمان ارائه دهيم. در اينصورت تابع تعريف شده در كلاس فرزند ، تابع هم نام والد را مخفي خواهد كرد و ديگر آن تابع والد فراخواني نخواهد گرديد. در اين حالت تنها يك راه براي دسترسي به تابع اصلي والد وجود دارد و آن استفاده از base. مي باشد كه در كد فوق پياده سازي شده است.
با استفاده از base. مي توان به تمام اعضاي public و يا protected كلاس والد از درون كلاس فرزند دسترسي داشت.
راه ديگري كه براي اين منظور وجود دارد در آخرين خط كد فوق در متد Main پياده سازي شده است :


((Parent)child).print();


براي تبديل نوع هاي مختلف در سي شارپ مي توان از پرانتز و سپس ذكر نوع اصلي استفاده كرد به اين عمل casting و يا boxing هم مي گويند. در كد فوق درحقيقت child به نوعي از parent تبديل شده است. بنابراين مانند اين است كه يك نمونه از كلاس والد متد print همان كلاس را فراخواني مي كند.

WooKMaN
21-11-2005, 14:02
مقدمه اي بر سي شارپ : قسمت پانزدهم


پلي مرفيسم (Polymorphism)

يكي ديگر از مفاهيم اوليه ي شيء گرايي پلي مرفيسم ( چند ريختي ) مي باشد. پلي مرفيسم به معناي توانايي استفاده كردن از فرم هاي مختلف يك نوع است بدون توجه به جزئيات آن .
براي مثال هنگاميكه سيگنال تلفني شما فرستاده مي شود ، از نوع تلفني كه در انتهاي خط موجود است خبري ندارد. تلفن انتهاي خط ، مي خواهد يكي از تلفن هاي عهد عتيق باشد و يا تلفني با آخرين امكانات روز .
شركت مخابرات (!) تنها از نوع پايه اي به نام phone خبر دارد و فرض مي كند كه هر instance از اين نوع مي داند كه چگونه صداي زنگ تلفن شما را به صدا در آورد. بنابراين شركت مخابرات از تلفن شما به صورت پلي مرف استفاده مي كند.
در عمل پلي مرفيسم هنگامي مفيد خواهد بود كه بخواهيم گروهي از اشياء را به يك آرايه نسبت دهيم و سپس متدهاي هر يك را فراخواني كنيم. الزاما اين اشياء از يك نوع نخواهند بود.

نحوه ي ايجاد متدهاي پلي مرفيك :
براي ايجاد متدي كه نياز است تا پلي مرفيسم را پشتيباني نمايد ، تنها كافي است آنرا از نوع virtual در كلاس پايه تعريف كنيم. مثال :
فرض كنيد تابع DrawWindow در كلاس Window تعريف شده است. براي ايجاد قابليت پلي مرفيسم در آن به صورت زير عمل مي شود :


public virtual void DrawWindow( )


در اين حالت هر كلاسي كه از Window مشتق شود ، مجاز است نگارش خاص خودش را از DrawWindow ارائه كند. در اين صورت در كلاسي كه از كلاس پايه ي ما ارث مي برد ، تنها كافي است كه كلمه ي كليدي override را قبل از نام تابع مذكور ذكر نماييم.

يك مثال كامل :


using System;

public class DrawingObject
{
public virtual void Draw()
{
Console.WriteLine("I'm just a generic drawing object.");
}
}
public class Line : DrawingObject
{
public override void Draw()
{
Console.WriteLine("I'm a Line.");
}
}

public class Circle : DrawingObject
{
public override void Draw()
{
Console.WriteLine("I'm a Circle.");
}
}

public class Square : DrawingObject
{
public override void Draw()
{
Console.WriteLine("I'm a Square.");
}
}
public class DrawDemo
{
public static int Main(string[] args)
{
DrawingObject[] dObj = new DrawingObject[4];

dObj[0] = new Line();
dObj[1] = new Circle();
dObj[2] = new Square();
dObj[3] = new DrawingObject();

foreach (DrawingObject drawObj in dObj)
{
drawObj.Draw();
}

return 0;
}
}


كلاس DrawingObject ، كلاسي پايه براي تمام كد ما كه از آن به ارث مي برد ، مي باشد. متد Draw در آن با كلمه ي كليدي virtual معرفي شده است. يعني تمام كلاس هاي فرزند اين كلاس والد مي توانند اين متد را override كنند ( تحريف كردن و يا تحت الشعاع قرار دادن هم ترجمه شده است! ).
در ادامه سه كلاس تعريف شده اند كه تمامي آنها از كلاس مبنا ارث مي برند و تابع Draw را تحريف كرده اند (!). با استفاده از كلمه ي كليدي override مي توان تابع مجازي كلاس مبنا را با تعريفي جديد در زمان اجراي برنامه ارائه داد. تحريف شدن تنها زماني رخ مي دهد كه كلاس ، توسط ريفرنس كلاس مبنا مورد ارجاع واقع شده باشد.
و در متد Main برنامه از اين كلاس ها در عمل استفاده گرديده است. در متد Main ، آرايه اي از نوع DrawingObject تعريف و مقدار دهي اوليه شده است تا بتواند 4 شيء از نوع اين كلاس را در خودش ذخيره كند.
بدليل رابطه ي ارث بري موجود مي توان آرايه ي dObj را با نوع هايي از كلاس هاي Line ، Circle و Square مقدار دهي كرد (همانند كدهاي بعدي متد Main ) . اگر ارث بري در اينجا وجود نمي داشت مي بايست به ازاي هر كلاس يك آرايه تعريف مي شد.
سپس از حلقه ي زيباي foreach براي حركت در بين اعضاي اين آرايه استفاده گرديده است. در اينجا هر شيء متد خاص خودش را در مورد Draw فراخواني مي كند و نتيجه را روي صفحه نمايش خواهد داد.
خروجي نهايي به صورت زير خواهد بود :


Output:
I'm a Line.
I'm a Circle.
I'm a Square.
I'm just a generic drawing object.

WooKMaN
21-11-2005, 14:03
مقدمه اي بر سي شارپ : قسمت شانزدهم


كلاس ها ي abstract
كلاس ها را همچنين مي توان به صورت abstract تعريف كرد. از اين نوع كلاس ها نمي توان instance ايي را ايجاد نمود. در اين كلاس هاي پايه ، صرفا تعريف متدها و خواص هايي عنوان گرديده و در آينده در كلاس هاي فرزند توسعه داده خواهند شد. براي مثال :


public abstract class Named
{
public abstract String Name {get; set;} // property
public abstract void PrintName(); // method
}
public class B : Named
{
private String name = "empty";
public override String Name
{
get{return name;}
set{name=value;}
}
public override void PrintName()
{
Console.WriteLine("Name is {0}", name);
}
}


والي كه شايد پيش بيايد اين است كه اگر interface ها صرفا تعريف توابع و خواص را مي توانند در خود جاي دهند پس چه دليلي براي بكار بردن آنها و طولاني كردن كار كد نويسي وجود دارد؟
كاربردهاي زيادي را مي توان براي اينترفيس ها برشمرد. اينترفيس يك رفتار را تعريف مي كند. فرض كنيد در حال توسعه ي برنامه ايي هستيد كه بر روي دو كامپيوتر مختلف بايد با هم در ارتباط مستقيم بوده و برهم كنش داشته باشند و هر برنامه از ماژولي به نام CCommObj communication object استفاده مي نمايد. يكي از متدهاي اين شيء ، SendData() مي باشد كه رشته اي را دريافت كرده و به برنامه ي ديگر مي فرستد. اين فراخواني از نوع asynchronous است زيرا ما نمي خواهيم اگر خطايي در شبكه رخ داد، برنامه براي هميشه منتظر باقي بماند. اما چگونه برنامه ي A كه تابع ذكر شده را فراخواني كرده است مي تواند تشخيص دهد كه پيغام به مقصد رسيده است يا خير و يا آيا خطايي در شبكه مانع رسيدن پيغام گشته است يا خير؟ جواب بدين صورت است كه CCommObj هنگام دريافت پيغام ، رخدادي را سبب خواهد شد و اگر خطايي رخ داده باشد خير. در اين حالت نياز به يك ماژول logging نيز احساس مي گردد تا خطاهاي رخ داده را ثبت نمايد. يك روش انجام آن اين است كه CCommObj پياده سازي اين امكان را نيز بعهده گرفته و اگر فردا نيز خواستيم ماژول ديگري را به برنامه اضافه كنيم هر روز بايد CCommObj را تغيير دهيم. تمام اين كارها را به سادگي مي توان در يك اينترفيس مدل كرد. روش آن نيز در ادامه بيان مي گردد:
در ابتدا يك اينترفيس ايجاد مي كنيم تا ليست تمام امكانات ممكن را "منتشر" كند:


interface ICommObjEvents
{
void OnDataSent();
void OnError();
}


شي ء CCommObj ما از اين توابع كه بعدا توسعه داده خواهند شد براي با خبر سازي كلاينت ها استفاده مي نمايد. تمام متدها در يك اينترفيس ذاتا پابليك هستند بنابراين نيازي به ذكر صريح اين مطلب نمي باشد و اگر اينكار را انجام دهيد كامپايلر خطاي زير را گوشزد خواهد كرد :


The modifier 'public' is not valid for this item


در ادامه كلاينت CClientApp_A را پياده سازي خواهيم كرد :


class CClientApp_A:ICommObjEvents
{
public void OnDataSent()
{
Console.WriteLine("OnDataSent");
}
public void OnError()
{
Console.WriteLine("OnError");
}
private CCommObj m_Server;
public void Init(CCommObj theSource)
{
m_Server = theSource;
theSource.Advise (this);
string strAdd = ("N450:1");
m_Server.read (strAdd,10);
}
}


در كد فوق كلاس CClientApp_A از ICommObjEvents ارث برده و تمام متدهاي اين اينترفيس را پياده سازي نموده است. هنگامي كه CCommObj تابع OnDataSent را فراخواني مي كند اين كلاينت پيغام را دريافت خواهد كرد. لازم به ذكر است كه كلاس كلاينت ما چون از يك اينترفيس ارث بري مي نمايد پس بايد تمام توابع و خواص كلاس پايه را پياده سازي كند در غير اينصورت هر چند برنامه كامپايل خواهد شد اما هنگامي كه شيء CCommObj هر كدام از توابع اين كلاس را فراخواني كد ، خطاي زمان اجرا رخ خواهد داد.
متد Init كلاس فوق آرگوماني را از نوع CCommObj دريافت نموده و در يك متغير private آنرا ذخيره مي نمايد. همچنين در اين متد ، متد Advise از كلاس CCommObj نيز فراخواني گشته است.


public class CCommObj
{
private int m_nIndex;
public ICommObjEvents [] m_arSinkColl;
public CCommObj()
{
m_arSinkColl = new ICommObjEvents[10];
m_nIndex = 0;
}
public int Advise(ICommObjEvents theSink)
{
m_arSinkColl[m_nIndex] = theSink;
int lCookie = m_nIndex;
m_nIndex++;
return lCookie
}
public void SendData(string strData)
{
foreach ( ICommObjEvents theSink in m_arSinkColl)
if(theSink != null )
theSink.OnDataSent ();
}
}


اين بحث ادامه دارد (لطفا با ما باشيد و جايي نرويد چون تازه بحث شيء گرايي شروع شده است!!) ....

WooKMaN
21-11-2005, 14:04
مقدمه اي بر سي شارپ : قسمت هفدهم


در كلاس CCommObj كه با آن آشنا شديم ، آرايه اي Private از نوع ICommObjEvents به نام m_arSinkColl وجود دارد. اين آرايه تمام اينترفيس هاي sink شده را ذخيره مي كند. واژه ي sink در اينجا به كلاسي گفته مي شود كه دريافت كننده ي رخدادها است. متد Advise تنها sink وارده به آنرا در يك آرايه ذخيره مي كند و سپس انديس آرايه را كه در اينجا cookie ناميده شده است بر مي گرداند. اين كوكي توسط كلاينتي كه ديگر نمي خواهد از آن آيتم هيچونه رخدادي را دريافت كند به سرور فرستاده مي شود و سپس سرور اين آيتم را از ليست خودش حذف خواهد كرد.

نحوه ي فراخواني متد advise توسط كلاينت نيز جالب است.


public void Init(CCommObj theSource)
{
m_Server = theSource;
theSource.Advise (this);
string strAdd = ("Hello");
m_Server.read (strAdd,10);
}


در اينجا تنها يك this بعنوان آرگومان به متد advice فرستاده شده است در حاليكه انتظار مي رفت آرگوماني از نوع ICommObjEvents به تابع فرستاده شود. دليل صحت اين عمل بدين صورت است كه كلاس ClientApp_A از اينترفيس ICommObjEvents ارث برده است و آنرا پياده سازي نموده است.
در ادامه ليست كامل برنامه ي نوشته شده را در حالت Console ملاحظه مي فرماييد.


namespace CSharpCenter
{

using System;

public interface ICommObjEvents
{
void OnDataSent();
void OnError();
}
public class CCommObj
{
private int m_nIndex;
public ICommObjEvents [] m_arSinkColl;
public CCommObj()
{
m_arSinkColl = new ICommObjEvents[10];
m_nIndex = 0;
}

public void Advise(ICommObjEvents theSink)
{

m_arSinkColl[m_nIndex] = theSink;
m_nIndex++;
}
public void SendData(string strData)
{
foreach ( ICommObjEvents theSink in m_arSinkColl)
{
if(theSink != null )
{
theSink.OnDataSent ();
}
}
}
}
class CClientApp_A:ICommObjEvents
{
public void OnDataSent()
{
Console.WriteLine("OnDataSent Client App A");
}
public void OnError()
{
Console.WriteLine("OnError");
}
public void Read()
{
string strAdd = ("Hello");
m_Server.SendData (strAdd);

}
private CCommObj m_Server;
public void Init(CCommObj theSource)
{
m_Server = theSource;
theSource.Advise (this);
}
}
class CClientApp_B:ICommObjEvents
{
public void OnDataSent()
{
Console.WriteLine("OnDataSent Client App B");
}
public void OnError()
{
Console.WriteLine("OnError");
}
private CCommObj m_Server;
public void Init(CCommObj theSource)
{
m_Server = theSource;
theSource.Advise (this);
}
}
class ConsoleApp
{
public static void Main()
{
CClientApp_A theClient = new CClientApp_A ();
CClientApp_B theClient2 = new CClientApp_B ();
CCommObj theComm = new CCommObj ();
theClient.Init (theComm);
theClient2.Init (theComm);
theClient.Read();

}
}

}


در متد Main برنامه ي فوق ، ما دو كلاينت تعريف كرده ايم و يك نمونه از CCommObj را. دو كلاينت instance هاي CCommObj را بعنوان آرگومان دريافت كرده اند. در هنگام فراخواني init توسط هر كلاينت متد advise فراخواني مي گردد. در خاتمه Read مربوط به كلاينت 1 فراخواني شده است كه سبب مي شود تا رخداد OnDataSend شيء CCommObj اجرا شود و به تمام كلاينت ها فرستاده شود.

هدف از اين مثال ارائه ي بعضي از جنبه هاي اينترفيس ها و نحوه ي استفاده از آنها بود. دو مطلب ديگر در مورد اينترفيس ها باقي مانده اند تا به پايان بحث مربوط به آنها برسيم:

چگونه مي توان متوجه شد كه يك شيء واقعا يك اينترفيس را پياده سازي كرده است؟
دو روش براي فهميدن اين موضوع وجود دارد:
- استفاده از كلمه ي كليدي is
- استفاده از كلمه ي كليدي as

اولين مثال زير از كلمه ي كليدي is استفاده مي كند :


CClientApp_C theClient3 = new CClientApp_C ();
if(theClient3 is ICommObjEvents)
Console.WriteLine ("theClient3 implements ICommObjEvents");
else
Console.WriteLine ("theClient3 doesnot implement ICommObjEvents");


كلمه ي كليدي is مقدار true را بر مي گرداند اگر اپراتور سمت چپ ، اينترفيس سمت راست را پياده سازي كرده باشد.


ICommObjEvents theClient5 = theClient3 as ICommObjEvents;
if(theClient5 != null )
Console.WriteLine ("Yes theClient implements interface");

else
Console.WriteLine ("NO,Yes theClient doesn't implements interface");


در مثال فوق اپراتور as در حال casting شيء theClient5 به ICommObjEvents مي باشد. چون CClientApp_C اينترفيس را پياده سازي نمي كند حاصل خط اول نال خواهد بود.

به صورت خلاصه :
يك اينترفيس قراردادي است كه به كلاينت گارانتي مي دهد يك كلاس خاص چگونه رفتار خواهد كرد. هنگاميكه كلاسي يك اينترفيس را پياده سازي مي كند به تمام كلاينت ها مي گويد كه : من تمام موارد ذكر شده در اينترفيس را ارائه و پياده سازي خواهم كرد. نمونه ي عملي استفاده از اينترفيس ها بحث dot net remoting است.

WooKMaN
21-11-2005, 14:05
مقدمه اي بر سي شارپ : قسمت هجدهم


مقابله با خطاها در سي شارپ (Exception Handling in C#)

EXCEPTION يك خطاي زمان اجر است كه بدليل شرايطي غيرنرمال در برنامه ايجاد مي شود. در سي شارپ exeption كلاسي است در فضاي نام سيستم. شيء ايي از نوع exception بيانگر شرايطي است كه سبب رخ دادن خطا در كد شده است. سي شارپ از exception ها به صورتي بسيار شبيه به جاوا و سي پلاس پلاس استفاده مي نمايد.

دلايلي كه بايد در برنامه exception handling حتما صورت گيرد به شرح زير است:
- قابل صرفنظر كردن نيستند و اگر كدي اين موضوع را در نظر نگيرد با يك خطاي زمان اجرا خاتمه پيدا خواهد كرد.
- سبب مشخص شدن خطا در يك نقطه از برنامه شده و ما را به اصلاح آن سوق مي دهد.

بوسيله ي عبارات try...catch مي توان مديريت خطاها را انجام داد. كدي كه احتمال دارد خطايي در آن رخ دهد درون try قرار گرفته و سپس بوسيله ي يك يا چند قطعه ي catch مي توان آنرا مديريت كرد. و اگر از اين قطعات خطايابي استفاده نشود برنامه به صورتهاي زير متوقف خواهد شد :


class A {static void Main() {catch {}}}
TEMP.cs(3,5): error CS1003: Syntax error, 'try' expected

class A {static void Main() {finally {}}}
TEMP.cs(3,5): error CS1003: Syntax error, 'try' expected

class A {static void Main() {try {}}}
TEMP.cs(6,3): error CS1524: Expected catch or finally


بهتر است يك مثال ساده را در اين زمينه مرور كنيم:


int a, b = 0 ;
Console.WriteLine( "My program starts " ) ;
try
{
a = 10 / b;
}
catch ( Exception e )
{
Console.WriteLine ( e ) ;
}
Console.WriteLine ( "Remaining program" ) ;
The output of the program is:
My program starts
System.DivideByZeroException: Attempted to divide by zero.
at ConsoleApplication4.Class1.Main(String[] args) in
d:\dont delete\consoleapplication4\class1.cs:line 51
Remaining program


برنامه شروع به اجرا مي كند. سپس وارد بلوك و يا قطعه ي try مي گردد. اگر هيچ خطايي هنگام اجراي دستورات داخل آن رخ ندهد ، برنامه به خط آخر جهش خواهد كرد و كاري به قطعات catch ندارد.
اما در اينجا در اولين try عددي بر صفر تقسيم شده است بنابراين كنترل برنامه به بلوك catch منتقل مي شود و صرفا نوع خطاي رخ داده شده نوشته و نمايش داده مي شود. سپس برنامه به كار عادي خودش ادامه مي دهد.

تعدادي از كلاس هاي exception در سي شارپ كه از كلاس System.Exception ارث برده اند به شرح زير هستند :


• Exception Class - - Cause
• SystemException - A failed run-time check;used as a base class for other.
• AccessException - Failure to access a type member, such as a method or field.
• ArgumentException - An argument to a method was invalid.
• ArgumentNullException - A null argument was passed to a method that doesn't accept it.
• ArgumentOutOfRangeException - Argument value is out of range.
• ArithmeticException - Arithmetic over - or underflow has occurred.
• ArrayTypeMismatchException - Attempt to store the wrong type of object in an array.
• BadImageFormatException - Image is in the wrong format.
• CoreException - Base class for exceptions thrown by the runtime.
• DivideByZeroException - An attempt was made to divide by zero.
• FormatException - The format of an argument is wrong.
• IndexOutOfRangeException - An array index is out of bounds.
• InvalidCastExpression - An attempt was made to cast to an invalid class.
• InvalidOperationException - A method was called at an invalid time.
• MissingMemberException - An invalid version of a DLL was accessed.
• NotFiniteNumberException - A number is not valid.
• NotSupportedException - Indicates sthat a method is not implemented by a class.
• NullReferenceException - Attempt to use an unassigned reference.
• OutOfMemoryException - Not enough memory to continue execution.
• StackOverflowException - A stack has overflown.


در كد فوق صرفا عمومي ترين نوع از اين كلاس ها كه شامل تمامي اين موارد مي شود مورد استفاده قرار گرفت يعني :


catch ( Exception e )


اگر نيازي به خطايابي دقيقتر باشد مي توان از كلاس هاي فوق براي اهداف مورد نظر استفاده نمود.

مثالي ديگر: ( در اين مثال خطايابي دقيق تر با استفاده از كلاس هاي فوق و همچنين مفهوم finally نيز گنجانده شده است )


int a, b = 0 ;
Console.WriteLine( "My program starts" ) ;
try
{
a = 10 / b;
}
catch ( InvalidOperationException e )
{
Console.WriteLine ( e ) ;
}
catch ( DivideByZeroException e)
{
Console.WriteLine ( e ) ;
}
finally
{
Console.WriteLine ( "finally" ) ;
}
Console.WriteLine ( "Remaining program" ) ;
The output here is:
My program starts
System.DivideByZeroException: Attempted to divide by zero.
at ConsoleApplication4.Class1.Main(String[] args) in
d:\dont delete\consoleapplication4\class1.cs:line 51
finally
Remaining program


قسمت موجود در قطعه ي فاينالي همواره صرفنظر از قسمت هاي ديگر اجرا مي شود.

به مثال زير دقت كنيد :


int a, b = 0 ;
Console.WriteLine( "My program starts" )
try
{
a = 10 / b;
}
finally
{
Console.WriteLine ( "finally" ) ;
}
Console.WriteLine ( "Remaining program" ) ;
Here the output is
My program starts
Exception occurred: System.DivideByZeroException:
Attempted to divide by zero.at ConsoleApplication4.Class1.
Main(String[] args) in d:\dont delete\consoleapplication4
\class1.cs:line 51
finally


قسمت چاپ Remaining program اجرا نشده است.

عبارت throw :

اين عبارت سبب ايجاد يك خطا در برنامه مي شود.

مثال :


int a, b = 0 ;
Console.WriteLine( "My program starts" ) ;
try
{
a = 10 / b;
}
catch ( Exception e)
{
throw
}
finally
{
Console.WriteLine ( "finally" ) ;
}


در اين حالت قسمت فاينالي اجرا شده و برنامه بلافاصله خاتمه پيدا مي كند.

WooKMaN
21-11-2005, 14:06
مقدمه اي بر سي شارپ : قسمت نوزدهم


سربارگذاري عملگر ها (Operator OverLoading)

به تعريف مجدد راه و روش اجراي عملگر ها توسط ما ، سربارگذاري عملگرها گفته مي شود. فرض كنيد مي خواهيد عدد 2 را به يك مقدار datetime اضافه كنيد. خطاي زير حاصل خواهد شد:


CS0019: Operator '+' cannot be applied to operands of type 'System.DateTime' and 'int'



جالب بود اگر مي توانستيم عدد 2 را به datetime اضافه كنيم و نتيجه ي آن تعداد روزهاي مشخص بعلاوه ي دو مي بود. اينگونه توانايي ها را مي توان بوسيله ي operator overloading ايجاد كرد.

تنها عملگر هاي زير را مي توان overload كرد:


Unary Operators
+ - ! ~ ++ -- true false

Binary Operators
+ - * / % & | ^ << >> == != > < >= <=



نحوه ي انجام اينكار نيز در حالت كلي به صورت زير است:


return_datatype operator operator_to_be_overloaded (agruments)
{
}



به مثال زير توجه كنيد:


using System;
class MyDate
{
public DateTime tempDate;
public MyDate(int year,int month,int day)
{
tempDate=new DateTime(year,month,day);
}
public static DateTime operator + (MyDate D,int noOfDays)
{
return D.tempDate.AddDays(noOfDays);
}
public static DateTime operator + (int noOfDays,MyDate D)
{
return D.tempDate.AddDays(noOfDays);
}
}

class Test
{
static void Main()
{
MyDate MD=new MyDate(2001,7,16);
Console.WriteLine(MD + 10 );
}
}

output:
2001-07-26



در مثال فوق عملگر + دوبار overload شده است. يكبار توسط آن مي توان يك عدد صحيح را به يك تاريخ اضافه كرد و بار ديگر يك يك تاريخ را مي توان به عدد صحيح افزود.


موارد زير را هنگام سربارگذاري عملگرها به خاطر داشته باشيد:

1- تنها اپراتورهاي ذكر شده را مي توان overload كرد. اپراتورهايي مانند new,typeof, sizeof و غيره را نمي توان سربارگذاري نمود.
2- خروجي متدهاي بكار گرفته شده در سربارگذاري عملگر ها نمي تواند void باشد.
3- حداقل يكي از آرگومانهاي بكار گرفته شده در متدي كه براي overloading عملگرها بكار مي رود بايد از نوع كلاس حاوي متد باشد.
4- متدهاي مربوطه بايد به صورت public و static تعريف شوند.
5- هنگامي كه اپراتور < را سربارگذاري مي كنيد بايد جفت متناظر آن يعني > را هم سربارگذاري نماييد.
6- هنگاميكه براي مثال + را overload مي كنيد خودبخود =+ نيز overload شده است و نيازي به كدنويسي براي آن نيست.


يكي از موارد جالب بكار گيري سربارگذاري عملگرها در برنامه نويسي سه بعدي و ساختن كلاسي براي انجام عمليات ماتريسي و برداري مي باشد.

WooKMaN
21-11-2005, 14:07
مقدمه اي بر سي شارپ : قسمت بيستم


Delegates

Delegates در سي شارپ روشي مطمئن و typesafe را براي بكار گيري مفهوم function pointer ارائه مي دهند. يكي از ابتدايي ترين استفاده هاي function pointers پياده سازي callback مي باشد. اما در ابتدا لازم است تا با اصول اوليه ي كاري آن آشنا شويم.

مثال يك :
يك delegate چگونه تعريف و استفاده مي شود؟
Delegate يك شيء است كه بيانگر يك تابع مي باشد بنابراين مي تواند بعنوان آرگومان ورودي يك تابع ديگر و يا عضوي از يك كلاس بكار رود.
در زبان "function-pointer" ، Func1() اشاره گري به Func2() را بعنوان پارامتر دريافت كرده و نهايتا آنرا فراخواني مي كند.
در زبان "delegate" ، Func1() يك شيء delegate از Func2() را دريافت كرده و سپس آنرا فراخواني مي كند.
در مثال زير از دو تابع براي شرح اين مطلب سود جسته شده است:
Func1() از delegate استفاده مي كند.
Func2() يك delegate است.

( شماره گذاري خطوط ، در كد زير ، صرفا براي راحت تر شدن توضيحات در مورد آنها است و لزومي به تايپ آنها در برنامه ي اصلي نيست. )


01 using System;
02 delegate void Delg(string sTry);
03 public class Example1{

// function which uses the delegate object
04 private static void Func1(Delg d){
05 d("Passed from Func1");
06 }

// function which is passed as an object
07 private static void Func2(string sToPrint){
08 Console.WriteLine("{0}",sToPrint);
09 }

// Main execution starts here
10 public static void Main(){
11 Delg d = new Delg(Func2);
12 Func1(d);
13 }
14 }


LINE 02
يك شيء delegate را براي Func2 تعريف مي كند.

LINE 04-06
تابعي را تعريف كرده است كه آرگومان ورودي آن از نوع Delg است.

LINE 07-09
تابعي را تعريف مي كند كه بايد به صورت delegate به تابع ديگر فرستاده شود.

LINE 10-14
تابع Main اجراي برنامه را با ايجاد يك شيء delegate براي Func2 آغاز كرده و سپس تابع Func1 را فراخواني مي كند.

مثال 2:
چگونه مي توان از delegates در كارهاي عملي استفاده كرد؟

طرح يك مساله:
شخصي تقاضاي ثبت نام در يك مؤسسه ي آموزشي و همچنين تقاضاي كاريابي در يك شركت را داده است. هر كدام از اين نهادها روشي خاص خود را براي ارزيابي شخص دارند.

راه حل (با روشي شيء گرا):
شخص مشخصاتي همچون سن / جنس / ميزان تحصيلات قبلي / تجربيات كاري و مدارك مرتبط دارد.
مؤسسه ي آموزشي تعدادي از اين مشخصات را براي ارزيابي شخص استفاده مي كند و اين امر در مورد شركت ياد شده نيز صادق است.
شيء شركت و شيء آموزشگاه هر كدام توابع ارزيابي خاص خودشان را پياده سازي مي كنند.
شخص ، اينترفيسي واحدي را در اختيار شركت / آموزشگاه براي ارزيابي خود قرار مي دهد.

پياده سازي (با استفاده از سي شارپ):
ما delegate‌ايي را تعريف مي كنيم كه بيانگر اينترفيسي است كه به شركت و آموزشگاه اجازه ي چك كردن شخص را مي دهد.
سه كلاس school و company و person را تعريف مي نماييم.
كلاس test را براي آزمودن اين موارد ايجاد مي كنيم.


01 using System;
02 using System.Collections;

03 public delegate bool GetChecker(Person p);

// Person has his information with him as he
// applies for School and Company
04 public class Person
05 {
06 public string Name;
07 public int Age;
08 public bool Graduate;
09 public int YearsOfExp;
10 public bool Certified;

11 public Person(string name,
int age,
bool graduate,
int yearsOfExp,
bool certified)
12 {
13 Name=name;
14 Age=age;
15 Graduate=graduate;
16 YearsOfExp=yearsOfExp;
17 Certified=certified;
18 }
19 public bool CheckMe(GetChecker checker)
20 {
21 return(checker(this));
22 }
23 }

// A school, the person applied for higher studies
24 public class School
25 {
26 public static bool SchoolCheck(Person p)
27 {
28 return (p.Age>10 && p.Graduate);
29 }
30 }

// A Company, the person wants to work for
31 public class Company
32 {
33 public static bool CompanyCheck(Person p)
34 {
35 return (p.YearsOfExp>5 && p.Certified);
36 }
37 }

// A Test class, displays delegation in action
38 public class Test
39 {
40 public static void Main()
41 {
42 Person p1 = new Person("Jack",20,true,6,false);
43 Console.WriteLine("{0} School Check : {1}",
p1.Name,
p1.CheckMe(new GetChecker(School.SchoolCheck)));
44 Console.WriteLine("{0} Company Check : {1}",
p1.Name,
p1.CheckMe(new GetChecker(Company.CompanyCheck)));
45 }
46 }


LINE 03
Delegate مورد نياز را تعريف مي كند.

LINE 04-23
كلاس person را تعريف مي كند. اين كلاس تابعي پابليك را ارائه مي دهد كه آرگومان ورودي آن از نوع GetChecker مي باشد.

LINE 24-30
كلاس school را تعريف مي كند و سپس تابعي را كه delegate است ارائه مي دهد.

LINE 31-37
كلاس company را تعريف مي كند و سپس تابعي را كه delegate است ارائه مي دهد.

LINE 38-36
كلاس test را پياده سازي مي نمايد. سپس يك شيء شخص ساخته مي شود. در ادامه new GetChecker(School.SchoolCheck) و new GetChecker(Company.CompanyCheck) شيء ايي را ايجاد مي كند از نوع delegate مورد نياز و آنرا به تابع CheckMe مي فرستد. خروجي نتيجه ي ارزيابي اين شخص مي باشد.

اگر چك كردن اشخاص بيشتري نياز باشد به اين صورت عمل مي شود:


Person p1 = new Person("Jack",20,true,6,false);
Person p2 = new Person("Daniel",25,true,10,true);
GetChecker checker1= new GetChecker(School.SchoolCheck);
GetChecker checker2= new GetChecker(School.CompanyCheck);

Console.WriteLine("{0} School Check : {1}",
p1.Name,p1.CheckMe(checker1));
Console.WriteLine("{0} Company Check : {1}",
p1.Name,p1.CheckMe(checker2));
Console.WriteLine("{0} School Check : {1}",
p2.Name,p2.CheckMe(checker1));
Console.WriteLine("{0} Company Check : {1}",
p2.Name,p2.CheckMe(checker2));


مثال 3 :
Delegates در تعامل بين دات نت فريم ورك و سي شارپ چه نقشي دارد؟

طرح يك مساله:
نمايش دادن ميزان پيشرفت خواندن يك فايل هنگامي كه حجم فايل بسيار زياد است.

راه حل ( با استفاده از سي شارپ):
در مثال زير از كلاس FileReader براي خواندن يك فايل حجيم استفاده شده است. هنگاميكه برنامه مشغول خواندن فايل است 'Still reading.. را نمايش مي دهد و در پايان 'Finished reading..'. را عرضه مي كند.
براي اينكار از فضاي نام System.IO استفاده شده است. اين فضاي نام حاوي delegate ايي مهيا شده براي ما مي باشد. بدين ترتيب مي توانيم به دات نت فريم ورك بگوييم كه ما تابعي را تعريف كرده ايم كه او مي تواند آنرا فراخواني كند.
سؤال: چه نيازي وجود دارد تا دات نت فريم ورك تابع ما را فراخواني و اجرا كند؟ با استفاده از تابع ما كه دات نت فريم آنرا صدا خواهد زد در طول خواندن فايل به ما گفته مي شود كه بله! من هنوز مشغول خواندن هستم! به اين عمليات Callback نيز گفته مي شود. به اينكار پردازش asynchronous نيز مي گويند!


01 using System;
02 using System.IO;

03 public class FileReader{
04 private Stream sInput;
05 private byte[] arrByte;
06 private AsyncCallback callbackOnFinish;

07 public FileReader(){
08 arrByte=new byte[256];
09 callbackOnFinish = new AsyncCallback(this.readFinished);
10 }

11 public void readFinished(IAsyncResult result){

12 if(sInput.EndRead(result)>0){
13 sInput.BeginRead(arrByte,
0,
arrByte.Length,
callbackOnFinish,
null);
14 Console.WriteLine("Still reading..");
15 }
16 else Console.WriteLine("Finished reading..");
17 }

18 public void readFile(){
19 sInput = File.OpenRead(@"C:\big.dat");
20 sInput.BeginRead(arrByte,
0,
arrByte.Length,
callbackOnFinish,
null);
21 for(long i=0;i<=1000000000;i++){
// just to introduce some delay
22 }
23 }

24 public static void Main(){
25 FileReader asynctest=new FileReader();
26 asynctest.readFile();
27 }
28 }


LINE 02
فضاي نام System.IO را به برنامه ملحق مي كند. اين فضاي نام به صورت خودكار حاوي تعريف delegate زير مي باشد:

public delegate void AsyncCallback (IAsyncResult ar);

LINE 03-10
تعريف كلاس

LINE 06
شيء delegate را تعريف مي كند.

LINE 07-10
سازنده ي كلاس را پياده سازي مي كنند. در اينجا ما تصميم گرفته ايم كه بافري حاوي 256 بايت را در هر لحظه بخوانيم.

LINE 09
شيء delegate نمونه سازي شده است.

LINE 18-23
readFile را پياده سازي مي كند.

LINE 12-16
نحوه ي استفاده از شيء IAsyncResult را بيان مي كند.

LINE 12
sInput.EndRead(result) تعداد بايتهاي خوانده شده را بر مي گرداند. اين خواندن تاجايي كه تعداد بايتهاي خوانده شده صفر است ادامه پيدا مي كند و در اينجا 'Finished reading..' اعلام مي گردد.

WooKMaN
22-11-2005, 22:44
معرفي اوليه VB.NET

يک برنامه کامپيوتري ، از مجموعه اي دستورالعمل که نوع و نحوه انجام يک فعاليت را براي کامپيوتر مشخص مي نمايند ، تشکيل مي گردد. دستورالعمل هاي نوشته شده بعنوان نمونه ممکن است به کامپيوتر اعلام نمايند که تعدادي از اعداد را با يکديگر جمع و يا دو عدد را بايکديگر مقايسه و بر اساس نتيجه بدست آمده ، اتخاذ تصميم نمايد. دستورالعمل هاي نوشته شده ، صرفا" براي کامپيوتر قابل فهم و اجراء خواهند بود.کامپيوتر دستورالعمل هاي نوشته شده را اجراء و ماحصل آن رسيدن به اهدافي خواهد بود که بر اساس آن برنامه طراحي و پياده سازي شده است . دستورالعمل ها ، مي بايست با استفاده از يکي از زبانها ي برنامه نويسي نوشته شده ( کد ينگ ) و در ادامه در اختيار کامپيوتر قرار داده شوند. زبانهاي برنامه نويسي متعددي نظير : فرترن ، بيسيک ، کوبال ، پاسکال، ،C ، جاوا ، ويژوال بيسيک و ... وجود دارد.
برنامه نويسي کامپيوتر ، مشابه آموزش گره زدن کفش به کودکان است . براي نيل به هدف فوق ، مي بايست تمامي مراحل لازم بصورت شفاف به کودکان آموزش داده شود . کودکان با دنبال نمودن دستورالعمل هاي ارائه شده ، قادر به گره زدن کفش خود خواهند بود ( روش انجام اين کار براي آنان مشخص شده و بر اساس آن ، امکان نيل به هدف مورد نظر توسط کودکان فراهم مي گردد ) . VB.NET ، زباني است که مي توا ن نحوه نيل به يک خواسته را بکمک آن بصورت شفاف ( نظير آموزش گره زدن کفش به کودکان ) مشخص و کامپيوتر با دنبال نمودن مراحل مشخص شده ، خواسته مورد نظر را محقق نمايد. با استفاده از VB.NET ، مي توان محصولاتي راايجاد که زمينه استفاده از آنان در محيط ويندوز و اينترنت ، وجود خواهد داشت . فراموش نکنيم در زمان فراگيري يک تکنولوژي در ابتدا مي بايست شيوه راه رفتن را بياموزيم و در ادامه اقدام به دويدن نمود .
VB.NET يکي از زبان هاي حمايت شده در دات نت مي باشد . با استفاده از زبان فوق علاوه بر اينکه مي توان برنامه هاي مبتني بر ويندوز را پياده سازي نمود ، امکان استفاده از آن بعنوان زبان مورد نظر در زمان ايجاد برنامه هاي مبتني بر وب که از تکنولوژي ASP.NET استفاده مي نمايند ، نيز وجود خواهد داشت . با توجه به اهميت و جايگاه خاص اين زبان در دات نت ، مجموعه مقالاتي در رابطه با آموزش اصولي اين زبان آماده شده که بتدريج بر روي سايت قرار خواهند گرفت . در اولين مقاله از اين مجموعه به معرفي اوليه VB.NET خواهيم پرداخت . در ابتدا لازم است با ويژگي هاي منحصر بفرد برنامه هاي مبتني بر ويندوز در قياس با برنامه هاي مبتني بر DOS ، آشنا شده و پس از مروري مختصر به روند شکل گيري نسخه هاي متعدد ويژوال بيسيک ، با نحوه نصب آن نيز آشنا شويم .

برنامه نويسي مبتني بر DOS در مقابل ويندوز
برنامه نويسي مبتني بر ويندوز داراي تفاوت هاي عمده اي نسبت به برنامه نويسي سنتي در محيط DOS است.برنامه هاي DOS ، مسيري دقيق و مشخص را ازابتدا تا پايان دنبال مي نمايند . رويکرد فوق ، باعث بروز محدوديت هائي در رابطه با عملکرد برنامه ها از يکطرف و تحميل محدوديت هائي به کاربران در طي نمودن مسير مشخص شده ، مي گردد. از زاويه اي خاص مي توان عملکرد يک برنامه مبتني بر DOS را مشابه قدم زدن در يک راهرو ( سالن )، در نظر گرفت . بمنظور رسيدن به نقطه انتهائي سالن ، مي بايست طول سالن طي تا به انتهاي آن رسيد . در اين راستا از موانع متعدد موجود در مسير ، مي بايست عبور تا سرانجام به مقصد مورد نظر رسيد . در زمان پيمودن مسير ، صرفا" امکان بازنمودن درب هاي خاصي ، وجود خواهد داشت . ويندوز ، دنياي جديدي از برنامه نويسي مبتني بر "رويداد" را ايجاد نموده است . کليک نمودن موس ، تغيير اندازه پنجره ، تغيير محتويات يک Textbox ، نمونه هائي از يک "رويداد" مي باشند. کدهاي نوشته شده ، نحوه برخورد با يک رويداد را مشخص مي نمايد. براي رسيدن به انتهاي يک سالن کافي است بر روي "انتهاي سالن " ، کليک نمود و ديگر ضرورتي به پيمودن تمامي مسير تا رسيدن به انتهاي سالن نخواهد بود . درصورتيکه به انتهاي سالن رسيده باشيم و متوجه گرديم که اين مکان ، محلي نيست که انتظار آن را داشته ايم ، بسادگي مي توان مقصد جديدي را براي خود انتخاب ، بدون اينکه ضرورتي به برگشت در نقطه آغازين مسير وجود داشته باشد. برنامه نوشته شده عکس العمل هاي لازم در ارتباط با حرکت شما را بهمراه عمليات مربوطه بمنظور تکميل فعاليت ها ي مورد نظر انجام خواهد داد . با استفاده از VB.NET ، مي توان کدهاي لازم بمنظور ارائه عکس العمل لازم در زمان تحقق يک رويداد را نوشت .در اين راستا ، برنامه نويسان مي توانند کدهاي لازم در رابطه با رويدادهائي که امکان تحقق آنها وجود دارد را نوشته تا در زمان بروز رويداد مورد نظر ، عکس العمل لازم از طرف برنامه صورت پذيرد.در اين زمينه مي توان از نوشتن کدهاي ديگر بمنظور برخورد با رويدادهاي غيرضروري ، صرفنظر کرد. مثلا" ويندوز قادر به تشخيص رويداد"کليک " از "کليک مضاعف " است . اين بدان معني است که اگر مي خواهيد برنامه مورد نظر شما ،عکس العمل لازم در ارتباط با رويداد "کليک" را داشته باشد ، مي بايست صرفا" کد مربوط به رويداد " کليک"، نوشته گردد و الزامي به نوشتن کدهاي لازم بمنظور برخورد با رويداد "کليک مضاعف" ، وجود نخواهد داشت . در دنياي برنامه نويسي DOS ، کاربر عکس العمل لازم را نسبت به برنامه انجام مي دهد در صورتيکه در ويندوز ، برنامه ها عکس العمل لازم را با توجه به رفتار کاربران ، انجام خواهند داد .
يکي ديگر از مزاياي مهم برنامه هاي ويندوز ، عدم وابستگي برنامه ها به يک سخت افزار خاص است . ويندوز تمهيدات لازم در خصوص ارتباط با سخت افزار را پيش بيني و برنامه نويسان نياز به آگاهي از نحوه عملکرد يک دستگاه سخت افزاري خاص بمنظور استفاده از آن ، نخواهند داشت . مثلا" برنامه نويسان ضرورتي به آگاهي از نحوه عملکرد هر نوع چاپگر ليزري، بمنظور ايجاد خروجي مورد نظر خود در برنامه ها ، نخواهند داشت. ويندوز، امکانات لازم در اين خصوص را از طريق ارائه روتين هاي عمومي که با درايورهاي مورد نظر مرتبط مي گردند ، فراهم مي نمايد. شايد همين موضوع دليل موفقيت ويندوز باشد .
روتين هاي عمومي اصطلاحا" Windows (API ) Application Programming Interface ناميده مي شوند .

تاريخچه ويژوال بيسيک
قبل از معرفي ويژوال بيسيک در سال 1991 ، پياده کنندگان نرم افزار مجبور به تسلط و مهارت در زمينه استفاده از ++C بهمراه موارد پيچيده اي در اين خصوص بودند . بدين ترتيب ، صرفا" افراد خاص آموزش ديده، قادر به خلق نرم افزارهاي قدرتمند بمنظور اجراء در محيط ويندوز بودند. ويژوال بيسيک ، محدوديت فوق را تغيير و مي توان اين ادعا را داشت که امروزه خطوط زيادي از برنامه هاي نوشته شده با استفاده از ويژوال بيسيک کد شده است . ويژوال بيسيک ، ظاهر برنامه نويسي تحت ويندوز را با حذف عمليات اضافي براي نوشتن کدهاي لازم جهت طراحي بخش رابط کاربر (UI) ، تغيير داده است . در اين راستا ، زمانيکه بخش رابط کاربر ، ترسيم مي گردد ، برنامه نويس مي تواند کدهاي لازم بمنظور انجام عکس العمل مناسب در رابطه با رويداد ها را به آن اضافه نمايد . زمانيکه ماکروسافت نسخه شماره سه ويژوال بيسيک را ارائه نمود ، مجددا" دنياي برنامه نويسي با تغيير مهمي مواجه گرديد. در اين راستا امکانات مناسبي براي نوشتن برنامه هاي مبتني بر بانک هاي اطلاعاتي ، در اختيار برنامه نويسان قرار گرفت. ماکروسافت بدين منظور محصول جديدي با نام DAO)Data Access Objects) را ارائه نمود . برنامه نويسان با استفاده از DAO ، امکان انجام عمليات متفاوت در رابطه با داده ها را ، بدست آوردند . نسخه هاي شماره چهار و پنج ، قابليت هاي نسخه سه را افزايش و اين امکان را براي پياده کنندگان نرم افزار فراهم نمود تا برنامه هاي خود را جهت اجراء در محيط ويندوز 95 ، طراحي و پياده سازي نمايند . در اين زمينه ، برنامه نويسان قادر به نوشتن کدهائي گرديدند که امکان استفاده از آنان توسط ساير پياده کنندگان نرم افزار که از زباني ديگر استفاده مي کردند، فراهم گرديد. نسخه شماره شش ويژوال بيسيک ، روش جديدي بمنظور دستيابي به بانک هاي اطلاعاتي را ارائه نمود: ADO)ActiveX Data Objects ) . يکي از اهداف اوليه طراحي ADO ، امکان دستيابي به بانک هاي اطلاعاتي براي پياده کنندگان برنامه هاي مبتني بر وب است که از تکنولوژي ASP ، استفاده مي نمايند.
همزمان با ارائه جديدترين نسخه ويژوال بيسيک که VB.NET ناميده مي شود ، بسياري از محدوديت هاي مرتبط با ويژوال بيسيک برطرف گرديد . در گذشته ويژوال بيسيک با انتفادات فراوان مواجه ( عدم وجود امکانات مناسب در مقايسه با جاوا و يا ++C ) و بسياري آن را نظير يک اسباب بازي در دنياي وسيع زبان هاي برنامه نويسي مي پنداشتند. VB.NET با غلبه بر مشکلات نسخه هاي پيشين ، توانسته است در مدت زمان کوتاهي ، بعنوان يک ابزار پياده سازي بسيار قدرتمند مطرح و گزينه اي مناسب براي برنامه نويسان در تمامي سطوح باشد .

نصب VB.NET
براي نصب VB.NET ، از دو رويکرد متفاوت مي توان استفاده کرد :

نصب بهمراه ويژوال استوديو دات نت

نصب نسخه استاندارد

هر يک از گزينه هاي فوق ، امکان ايجاد برنامه هاي مبتني بر ويندوز را فراهم مي نمايند . مراحلي که در ادامه ذکر مي گردد ، نحوه نصب ويژوال استوديو را تشريح مي نمايد .

مرحله اول : برنامه Setup.exe را از روي CD مربوطه فعال نمائيد.

مرحله دوم : جعبه محاوره اي ، مراحل و اولويت هاي عمليات نصب را نشان خواهد داد. بمنظور صحت عملکرد VB.NET ، چندين Component نصب و يا بهنگام خواهند شد . اولين مرحله نصب، بهنگام سازي عناصر (Components) است . بر روي گزينه Windows Component Update ، کليک نمائيد.

مرحله سوم : برنامه نصب در ادامه سيستم را بررسي تا نوع عناصري را که مي بايست بهنگام گردند، مشخص گردد. دامنه فرآيند بهنگام سازي به وضعيت ماشيني که بر روي آن ويژوال استوديو دات نت نصب مي گردد، بستگي خواهد داشت .

مرحله چهارم : با توجه به اينکه ممکن است در زمان بهنگام سازي لازم باشد چندين مرتبه سيستم راه اندازي گردد ، از شما درخواست نام و رمز عبور شده تا ضرورتي به نشستن و نگاه کردن به کامپيوتر و واکنش لازم ( درج نام و رمز عبور به سيستم ) پس از هر مرتبه راه اندازي سيستم نباشد . بدين ترتيب در زمان راه انداري سيستم ، عمليات مربوطه بصورت اتوماتيک و بدون نياز به تايپ نام و رمز عبور ، انجام خواهد شد . عمليات فوق ، اختياري است و در صورتيکه گزينه فوق انتخاب نگردد ، با هر مرتبه راه اندازي سيستم، پيام مناسب ارائه و مي بايست واکنش لازم ( تايپ نام و رمز عبور) را انجام داد .

مرحله پنجم : در اين مرحله با فشردن دکمه ! Install Now ، بهنگام سازي عناصر (Components) آغاز مي گردد . با اتمام هر يک از آيتم ها يک Check mark بمنزله اتمام مرحله مربوطه نشان داده مي شود . در مقابل عنصر جاري براي بهنگام سازي نيز يک فلش قرمز رنگ نسان داده مي شود.

مرحله ششم : پس از بهنگام سازي عناصر ، مجددا" به صفحه اصلي Setup مراجعت و امکان نصب ويژوال استوديو دات نت فراهم مي گردد.( کليک نمودن برروي گزينه Visiual Studio.NET )
نکته : در صورتيکه قصد داريد که از طريق ماشين فوق ، يک برنامه تحت وب پياده سازي نمائيد ، لازم است IIS و FrontPage Extensions قبلا" نصب شده باشد( بصورت پيش فرض در زمان نصب ويندوز 2000 نصب خواهد شد ) در صورتيکه ويژوال استوديو دات نت ، بر روي کامپيوتري نصب مي گردد که داراي سيستم عامل ويندوز 2000 نسخه Professional است ، با يک پيام خطاء مواجه خواهيم شد( عدم وجود عناصر لازم ) با فشردن دکمه Install Component ، عمليات نصب IIS و Frontpage Extensions انجام خواهد شد . در صورتيکه دکمه Continue ، انتخاب گردد ، در آينده نمي توانيد برنامه هاي تحت وب را بصورت محلي بر روي کامپيوتر خود پياده سازي نمائيد .

مرحله هفتم : نظير اکثر برنامه هاي نصب ، ليستي از گزينه هاي موجود ( شامل عناصر ) براي نصب در اختيار شما قرار مي گيرد . شما مي توانيد ، صرفا" آنچيزي را که بدان نياز داريد ، نصب نمائيد . مثلا" در صورتيکه ظرفيت درايو شما پايين و يا ضرورتي به استفاده از ويژوال ++C دات نت را نداريد ، مي توان در اين مرحله از نصب آن صرفنظر کرد. هر گزينه اي که در اين مرحله انتخاب نمي گردد ، مي توان در صورت ضرورت آن را در آينده نصب کرد. براي هر يک از امکاناتي که قرار است نصب گردند ، سه بخش اطلاعاتي متفاوت نمايش داده مي شود :
بخش Feature Properties . فايل ها ي مورد نظر براي نصب و ميزان فضاي مورد نياز را نشان مي دهد .
بخش Feature description . هر Feature چيست و چه عملياتي را انجام مي دهد .
بخش Space Allocation ، وضعيت فضاي ذخيره سازي هارد را با توجه به گزينه هاي انتخاب شده ، نشان خواهد داد .
نکته : زمانيکه ويژوال استوديو دات نت ، اجراء مي گردد مجموعه اي از اطلاعات بين ديسک و حافظه مبادله مي گردد . بنابراين لازم است به ميزان کافي ظرفيت آزاد بر روي هارد ديسک وجود داشته باشد ، در اين راستا نمي توان دقيقا" مشخص نمود که به چه ميزان فضاي آزاد نياز خواهد بود ولي حداقل يکصد مگابايت توصيه مي گردد .

مرحله هشتم : ويژوال استوديو دات نت ، شامل مجموعه اي گسترده از فايل هاي مستندات ( راهنما ) است . در اين مرحله مي توان تنظيمات لازم در خصوص اجراي مستندات از طريق CD و يا دايرکتوري نصب شده بر روي هارد را انجام داد . در اين زمينه مي توان يک مسير بر روي هارد را مشخص تا مستندات نصب و يا گزينه Run From Source را انتخاب تا بر اساس آن مستندات همچنان بر روي CD باقي بمانند .

مرحله نهم : پس از انتخاب عناصر مورد نظر براي نصب ، با فشردن دکمه ! Install Now ، عمليات نصب آغاز مي گردد . مدت زمان نصب ، بستگي به موارد انتخابي و نوع سيستم دارد . مثلا" نصب تمام ويژوال استوديو دات نت بهمراه تمامي مستندات بر روي يک ماشين با دارا بودن 256 مگابايت حافظه اصلي، سرعت 650 مگاهرتز و دوازده گيگابايـت هارد ديسک ، حدود يک ساعت طول خواهد کشيد .

مرحله دهم : پس از اتمام مرحله قبل ، با انتخاب گزينه Service Release ، بررسي لازم در خصوص بهنگام سازي انجام مي گيرد . اين عمليات از طريق اينترنت انجام خواهد شد . در اين زمينه به يک خط پرسرعت و مطمئن نياز خواهد بود .

پس از انجام مراحل فوق ، ويزوال استوديو دات نت بر روي سيستم نصب و محيط لازم براي نوشتن برنامه هاي VB.NET فراهم شده است .

WooKMaN
22-11-2005, 22:52
مقايسه ADO و ADO.NET


شركت مايكروسافت در ويژوال بيسيك ورژن 3 كه در سال 1993 ارائه داد از Jet كه هسته اصلي MS Access بود براي ايجاد ارتباط با بانكهاي اطلاعاتي استفاده نمود البته براي استفاده بهتر برنامه نويسان ، Jet را در غالب مجموعه Object هائي تحت عنوان (Data Access Object ) آورد. در نسخه 4 و 5 ويژوال بيسك ، ماكروسافت روشي ديگر براي ارتباط با بانكهاي اطلاعاتي تحت عنوان (Remote Data Object ) RDO را مطرح ساخت اين روش براي برنامه نويسي Client / Server روش مناسبي بود.

در دوم سپتامبر سال 1998 وقتي ماكروسافت ويژوال بيسيك ورژن 6 را ارائه داد روش جديدي تحت عنوان ( Activex Data Object ) ADO را مطرح ساخت در اين روش كه پايه و اساس آن OLEDB بود ماكروسافت بر خلاف DAO و RDO كه ساختاري پيچيده و سلسله مراتبي داشتند، از ساختاري ساده و مجزا ( غير سلسله مراتبي ) استفاده كرد و در واقع ADO هم شامل Object هائي است كه برنامه نويس بتواند از آنها براي ايجاد ارتباط با بانكهاي اطلاعاتي و انجام عمليات روي آنها استفاده كند و در تاريخ 13 February سال 2002 كه ماكروسافت نسخه نهائي Visual Basic.Net را ارائه داده روشي جديد براي كار با بانكهاي اطلاعاتي تحت عنوان ADO.Net را آورده است. اين نسخه از ويژوال بيسيك برخلاف نسخه‎هاي قبل بطور كامل مباحث OOP را پشتيباني مي‎كند ( FULL OOP ) در واقع ADO.Net هم مانند ADO و RDO و ADO شامل ساختاري براي ارتباط و انجام عمليات روي بانكهاي اطلاعاتي است. ADO.net همانند RDO و DAO و برخلاف ADO داراي ساختار سلسله مراتبي مي‎باشد. در اين مقاله مي‎خواهيم به مقايسه ADO و ADO.net بپردازيم. ADO در ورژنهاي مختلفي در اين چند سال اخير به بازار آمده است با آمدن SQL Server 2000 ورژن جديد ADO يعني ورژن 2.6 از اين محصول ارائه شد و اكنون هم ADO 2.6 در سايت ماكروسافت قابل Download مي‎باشد.

آخرين ورژن ADO شامل 9 تا Object است كه عبارتند از :

Connection
Command
Recordset
Parameter
Field
Error
Property
Record
Stream

آبجكت Connection امكان ارتباط با Data Source كه شامل بانك اطلاعاتي است را فراهم مي‎سازد. بعنوان مثال اگر بخواهيم از آبجكت Recordset براي اضافه و يا حذف و يا تغيير در محتواي ركوردي استفاده كنيم اين آبجكت از Connection براي ايجاد ارتباط با بانك اطلاعاتي مثلاً SQL Server استفاده مي‎كند اما همانطور كه گفته شد و در شكل ملاحظه مي‎شود ساختار آبجكتهاي ADO بصورت سلسله مراتبي نيست و مي‎‎توان مثلا Recordset اي ايجاد نمود كه مستقل از آبجكت Connection بتواند با بانك اطلاعاتي ارتباط برقرار نمايد.




در ADO علاوه بر آبجكتها، چهار Collection هم ديده مي‎شود كه عبارتند از :

Parameters
Fields
Properties
Errors

كه هركدام از آنها شامل آبجكتهائي از همان نوع هستند بعنوان مثال ساختاري كه براي Recordset كشيده شده بيان كننده آن است كه اين آبجكت شامل Collection هاي Fields و Properties بوده و مثلاً Collection مربوط به Fields شامل آبجكتهاي فيلد است.

آبجكت فيلد اطلاعاتي را راجع به يك ستون از Recordset در خود نگه داشته است.


در ADO آبجكت Command هم وجود دارد كه از آن مي‎توان براي اجراي يك فرمان SQL استفاده نمود البته بهترين روش براي اجراي Stored Procedure نيز استفاده از متد Execute مربوط به همين آبجكت است .

بعنوان مثال :

Dim cn As New ADODB.Connection
Dim cmd As New ADODB.Command
Dim rs As New ADODB.Recordset

cn.Open " Provider = sqloledb ; Data Source=serverName ; Initial Catalog = northwind ", "sa" , "password"
cmd.ActiveConnection = cn
cmd.CommandText = "sp_who"
cmd.CommandType = adCmdStoredProc

Set rs = cmd.Execute
Debug.Print rs(0)
rs.Close

از آبجكت Parameter هم براي مشخص كردن مقادير پارامترهاي ورودي يك ‌ Stored Procedure استفاده مي‎كنيم.

آبجكت Property براي استفاده از Dynamic Property استفاده مي‎شود كه Property هايي هستند كه وابسته به Provider بوده و استاندارد نيستند .

از Record براي دسترسي به يك سطر از Recordset و ويژگيهاي مربوط به آن سطر استفاده مي‎كنيم .و آبجكت Stream هم به منظور ذخيره و بازيابي اطلاعات بصورت باينري در يك فيلد از Record در نظر گرفته شده است.

تا اينجا باساختار ADO آشنا شديم حال به تشريح ADO.net مي‎پردازيم .

ADO.Net مجموعه‎اي از Class هاي Interface ها و دستوراتي جهت مديريت و كار با بانكهاي اطلاعاتي است. در بحث Net . مجموعه‎اي از Class هاي مربوط به هم در يك غالب تحت عنوان ‌ Name Space ارائه شده است Net. شامل تعدادي Name Space است كه در غالب .Net Framework قرار دارد. تمام ساختار ‌ ADO.net در چهار NameSpace قرار دارد كه عبارتند از :

System.Data.SqlClient.
System.Data.OleDb.
System.Data.Odbc.
System.Data.

اگر بخواهيم از بانكهاي SQL Server استفاده كنيم System.Data.SqlClient بهترين انتخاب است در اين NameSpace امكاناتي فراهم شده تا بتوانيم Application هاي بنوسيم و در آنها با SQL Server ارتباط برقرار نمائيم بطوريكه برنامه‎ها از Performance بالائي برخوردار باشند.

در صورتي كه كاربر بخواهد از بانكهاي رابطه ‎اي ديگر نظير Oracle استفاده كند ميتواند از System.Data.OleDb بهره گيرد.

System.Data.Odbc براي ارتباط با بانكهاي اطلاعاتي از طريق ODBC ميباشد System.Data هم شامل Provider هاي خاص نظير DataSet و DataTable است. ADO.net نيز شامل Object ها و Collection هائي است كه از مهمترين آنها مي‎توان موارد ذيل را شمرد:

OleDBConnection
OleDBCommand
OledbDataReader
OleDBDataAdapter
SelectCommand
InsertCommand
UpdateCommand
DeleteCommand
DataTable
DataRelation



OleDBConnection آبجكتي است شبيه به آبجكت Connection در ‌ ADO ، كه امكان ايجاد ارتباط با بانك را فراهم مي‎سازد اين آبجكت متدهايي براي اجراي فرامين SQL نيز داراست .OleDBCommand هم مشابه آبجكت Command در ‌ ADO مي‎باشد.

از اين آبجكت نيز براي اجراي Stored Procedure و اجراي فرامين SQL استفاده مي‎شود. آبجكت بعد OledbDataReader است كه براي گرفتن اطلاعات از ‌Database استفاده مي‎شود. البته لازم به ذكر است Resultset اي كه با اين روش ساخته مي‎شود بصورت ReadOnly و Forwardonly مي‎باشد. OleDBDataAdapter آبجكت جديدي در Ado.net است كه خود شامل چهار آبجكت براي انجام فرامين SQL مي‎باشد كه عبارتند از :

SelectCommand
InsertCommand
UpdateCommand
DeleteCommand

كه به ترتيب براي واكشي اطلاعات، اضافه نمودن اطلاعات جديد به داخل بانك ، به هنگام سازي اطلاعات و حذف اطلاعات استفاده مي‎شود. اين آبجكت به همراه آبجكت Dataset استفاده مي‎شود و براي پركردن Recordset موجود در Dataset بكار مي‎رود.



آبجكت بعدي Dataset است كه مهمترين آبجكت در Ado.net مي‎باشد اين آبجكت شامل دو Collection به نام هاي ‌ DataTables و DataRelations است. همانطور كه مي‎دانيد در ADO هم آبجكت Recordset داشتيم اينجا مجموعه‎اي از Recordset ها در داخل يك DataTables نگه داشته مي‎شود و مي‎توان بين DataTable هاي مختلف رابطه نيز ايجاد نمود كه اين روابط هم داخل يك مجموعه‎اي با نام DataRelations نگه داشته مي‎شود. در واقع DataTable در ADO.net معادل همان RecordSet در ADO مي‎باشد.

مراجع :

1. VB.NET for Developers , Keith Franklin , SAMS Visual
2. Basic Developer's Guide to SQL Server , Dianne Siebold , SYBEX
3. MSDN

WooKMaN
23-11-2005, 08:23
آموزش پاسکال قسمت اول

زبان پاسكال يكي از زبانهاي برنامه سازي است كه ويژگيهاي آموزشي آن بسيار بالاست يعني زبان خوبي براي آموزش برنامه نويسي منظم و دقيق است.قابليت خوانايي و درك برنامه هاي اين زبان بالاست وميتوان برنامه هايي نوشت كه احتمال خطاهاي آنها بسيار اندك باشد علتش اين است كه يك زبان ساختار يافته (structed) است .

ساختار كلي برنامه چيست؟
1-تعريف
2-به وسيله procedure و functionقسمتهاي تكراري را از بين ببريم
3-بدنه
فرم كلي پاسكال:

;اسم Program
; تعريف ثابت const
; تعريف نوع type
; تعريف متغيرها var
( پارامترها ) نام procedure
begin
____
____
____
end ;
;نوع تابع ( پارامترها ) نام function
begin
____
____
____
end ;
begin
____
____
____
end .

متغير : محلي است كه داراي يك اسم مي باشد و مي توان مقداري را در آن ذخيره كرد

انواع متغيرها در پاسكال:
Integer :انواع عددي صحيح شامل اعداد بدون نقطه مميز است
نوع مقاديري كه مي پذيرند طول(بايت)
byte 0 تا 255 1
Shortint 128- تا 127 1
integer 32768- تا 32767 2
Word 0 تا 65535 2
Longint 2147483648- تا 2147483647 4



اعداد اعشاري:
انواع عددي اعشاري شامل اعدادي با نقطه مميز است

نوع مقاديري كه ميپذيرند ارقام با معني طول(بايت)

single 1.5e-45 تا3.4e38 7 تا 8 4
real 2.9e-39 تا 1.7e38 11 تا 12 6
Double 5.0e-324تا 1.7e308 15 تا 16 8
extended 1.9e-4951تا 1.1e493 19 تا 20 10

انواع داده هاي اعشاري

-Char :
نوع داده كاراكتري كه با كلمه char مشخص مي شود ميتواند يك كاراكتر را در خود نگهداري كند بنابراين كاراكترها در يك بايت از حافظه كامپيوتر ذخيره مي شوند

String - :
اين نوع داده ها براي ذخيره رشته ها مثل اسامي افراد به كار مي رود و با كلمه كليدي string مشخص ي گردد
براي هر رشته بايد طول معلوم كنيم اگر طولي تعريف نشود به طور پيش فرض 80 در نظر گرفته ميشود(مقدار طول حداكثر 255 است)
- Boolean :
نوع ديگري از داده ها در پاسكال وجود دارند كه داده هاي بولي خوانده مي شوند مقادير بولي داراي دو ارزش درستي يا نادرستي اند كه در پاسكال با صفر و يك نمايش داده مي شوند صفر به معني نادرستي و يك به معني درستي به كار ميرود اين نوع داده ها با كلمه Boolean تعريف ميشوند.
دستورات ورودي در پاسكال:
دستور Readlnبراي خواندن اطلاعات از ورودي به كار ميرود.
فرمت آن به صورت مقابل است:
(اسامي متغيرها)read/ln
اسامي متغيرها بايد با كاما از يكديگر جدا شوند..
براي چاپ اطلاعات در خروجي از دستور write/ln استفاده ميكنيم.
فرمت آن به صورت مقابل است:
' يك پيام '
( متغير ) write/ln
عبارت محاسباتي
انتساب متغيرها:
مقدار ثابت
( متغير )=: متغير
عبارت محاسباتي

مثال : برنامه اي بنويسيد كه دو عدد را از ورودي دريافت و حاصلجمع آن دو را چاپ كند .

Program add;
Var
a,b:integer;
begin
writeln('enter 2 num');
readln(a,b);
c:=a+b;
writeln('result is =',c);
end.


تكليف : چرا برنامه بايد ادب داشته باشد ؟
مثال : برنامه اي بنويسيد كه حقوق پايه وتعداد فرزندان يك كارگر را از ورودي دريافت و مبلغ حقوق وي را بر اساس فرمول زير حساب كنيد.
10*تعداد فرزندان + حقوق پايه =حقوق كل

Program test;
Var
Salary:longint;
Child:byte;
kole:integer
Begin
Writeln('enter salary and number of child);
Readln(salary,child);
Kole := salary + child *10
Writeln('kole is ',kole);
END.

اولويت عملگرها:

/ *
- +
شرط:
then شرط if
Begin
____
____
____
end
else
begin
____
____
____
end;

نكته : دستورالعمل قبل از IF سمي كالن نمي گيرد
عناصر شرط:
< > <= >= = <>
اپراتورها :

AND OR NOT XOR
NOT A
1 0
0 1

XOR OR AND B A
0 1 1 1 1
1 1 0 0 1
1 1 0 1 0
0 0 0 0 0


مثال : برنامه اي بنويسيد كه با دريافت دو عدد بزرگترين آنها را چاپ كند.

Program test;
Var
a,b:integer;
if a>b then
begin
writeln(a);
end
else
writeln(b);
end.


مثال : برنامه اي بنويسيد كه با دريافت سه عدد به عنوان ضرايب y=ax2+bx+c معادله درجه دو را حل كند(اين برنامه را با يك If بنويسيد).

Var
A,b,c:integer;
D,x1,x2:real;
Begin
Writeln('enter a,b,c');
Readln(a,b,c);
D:=b*b-4*a*c;
If (d >=0 ) then
Begin
X1:=(-b+sqrt(d))/2*a);
X1:=(-b-sqrt(d))/2*a);


مثال : برنامه اي بنويسيد كه تعداد فرزندان وحقوق پايه و رتبه يك كارگر را از ورودي دريافت و حقوق كل وي را بر اساس فرمول زير حساب كند.
كسريها - مزايا +بيمه = حقوق كل
5*رتبه +1000* تعداد فرزند = مزايا
ماليات + بيمه = كسريها

بيشتر كمتر يا مساوي 2 تعداد فرزند
تعداد فرزندان 1000 بيمه
هر چيزي ديگر 20 تا 0 رتبه
حقوق پايه حقوق پايه*100/10 ماليات


begin
writeln('enter salary and grade and number of child');
readln(salary ,num,grade);
if num<=2 then
bimeh:=100
else
bimeh :=num*500;
if (grade>=0) and (grade<=20)then
net := 10/100*salary
else
if grade >20 then
begin
net:=20/100*salary;
mazaya:=num*1000+grade*50;
kasry:=bimeh+net;
kol :=salary + mazaya-kasry;
end;
writeln(kol);
end.


تكليف : در يك تركيب شيميايي 4 عنصر شركت دارند مقدار مجاز براي تهيه ماده اي به نام asxd به اين صورت است.
A 0 ~ 50
S 0.5 ~ 0.83
X 81 ~ 92 or 824 ~ 901
D -100 ~ 100
با دريافت مقادير a,s,x,d از ورودي به ما بگويد كه آيا مي توان اين ماده را توليد كرد يا نه ؟

Begin
Num:=0;
Writeln('please enter a s x d');
Readln(a,s,x,d);
If (a>0) and(a<50) then
Num:=num+1;
If (s>0.5)and (s<0.83) then
Num:=num+1;
If ((x>81)and(x<92))or ((x>824)and(x<901))then
Num:=num+1;
If (d>-100) and (d<100) then
Num:=num+1;
If num=4 then
Writeln('yes can')
Else
Writeln('you can not');
End.

تكليف : برنامه اي بنويسيد كه با دريافت سه عدد و با فرض اينكه عدد دوم وتر ميباشد به ما بگوييد كه آيا اين سه عدد تشكيل يك مثلث قايم الزاويه مي دهد يا خير؟

-CASE:
CASE ميتواند تعداداي شرط را بگيرد و انتخاب كند.
مقاديري كه دستور CASE ميپذيرد ORDINAL است مقاديري كهORDINAL هستند داراي تركيب نيستند و همچنين قابل شمارش هم هستند مثل INTEGER,CHARACTER,BYTE,BOOLEAN,LONGINT,…
پسREAL,STRING ORDINAL<---- نيستند
CASE تنها دستوري است كه BEGIN ندارد ولي END دارد
مقدارها ميتوانند شامل يك مقدار يا چند مقدار كه از يكديگر با كاما جدا شده اند باشند و يا يگ سري شمارشي باشند مثل:

1:------
1,10,28:------
1..100,150..243:---------
'A'..'Z':---------

Of متغير Case
Begin : مقدار1
-------
-------
End;
Begin : مقدار2
-------
-------
End;
Begin :Else
-------
-------
End;
End.

مثال : برنامه اي بنويسيد كه يك عدد را از ورودي دريافت ( (0<=x<3وتلفظ آنها را چاپ كند.

BEGIN
READLN(X);
CASE X OF
0:WRITELN('ZERO');
1:WRITELN('ONE');
2:WRITELN('TWO')
ELSE
WRITELN('ERROR');
END;
END.

WooKMaN
23-11-2005, 08:24
آموزش پاسکال قسمت دوم


مثال : برنامه اي بنويسيد كه دو عدد را از ورودي دريافت و چنانچه عدد اول در بازه 0 تا 5 بود توان دوم عدد دوم را چاپ كند چنانچه 68 بود حاصلضرب دو عدد را چاپ كند و در غير اينصورت مقادير مجاز را چاپ كند.

BEGIN
WRITELN('ENTER TWO NUMBER');
READLN(A,B);
CASE A OF
0..5 :WRITELN(B*B);
68:WRITELN(A*B)
ELSE
WRITELN('ENTER 0..5 OR 68');
END;
END.

- معادل برنامه بالا با دستور If :


Begin
Writeln('enter 2 number');
Readln(a,b);
If (a>=0)and(a<=5) then
Writeln(b*b)
Else
If a=68 then
Writeln(a*b)
Else
Writeln('enter 0..5 or68');
End.

تكليف : روشي براي تلفظ اعداد پيدا كنيد.

حلقه تكرار :
1- تعداد معين
2- تعداد معين
Do مقدار نهايي to { مقدار شروع=: متغير for
downto
begin
___
___
___
end;
توجه مهم : در برخي از حلقه ها دستورات داخل حلقه به متغير حلقه مرتبط مي باشند و در برخي موارد هيچگونه ارتباطي وجود ندارد.
حلقه for براي تعداد تكرار معين به كار ميرود
Downto : در مواردي به كار ميرود كه مقدار اوليه از مقدار نهايي بيشتر باشد

مثال : برنامه اي بنويسيد كه توان دوم اعداد 100 تا 200 را چاپ كند.

Begin
For i:=100 to 200 do
Begin
Writeln(i*i);
End;
End.

نكته : اجازه نداريد مقدار متغير حلقه را در داخل بدنه عوض كنيد .
مثال : برنامه اي بنويسيد كه حاصلجمع اعداد 100..1 را چاپ كند.

Begin
Sum:=0;
For i:=1 to 10 do
Begin
Sum:=sum+i
End;
Write(sum);
End.



مثال : برنامه اي بنويسيد كه حاصلجمع مضارب 5 بين 0 تا 100را به دست آورد.

Begin
Sum:=0;
For I:=1 to 20 do
Begin
Sum:=sum+i*5;
End;
Writeln(sum);
End.

مثال : برنامه اي بنويسيد كه دو عدد را از ورودي دريافت و اعداد ما بين اين دو عدد را چاپ كند (a
Begin
Writeln('enter a,b');
Readln(a,b);
For I:= a to b do
Writeln(i);
End.


مثال : برنامه اي بنويسيد كه با يك حلقه for اعداد بين100..1 و738..353و 950..940 را چاپ كند

Begin
For i:=1 to 950 do
Begin
If ( i>=1) and (i<=100) then
Writeln(i);
If (i>353) and (i<=738) then
Writeln(i);
If (i>=940) and (i<=950) then
Writeln(i);
End;
End.

معادل برنامه بالا با استفاده از دستور case :

Begin
For i:=1 to 950 do
Case I of
1..100,353..738,940..950: writeln(i);
end;
end.


)باقيمانده)mod?
مثال :
X mod y
مثال : برنامه اي بنويسيد كه مضارب 7 بين 1 تا 100 را چاپ كند

Begin
For i:= 1 to 100 do
Begin
If I mod 7 = 0 then
Writeln(i);
End;
End.

مثال : برنامه اي بنويسيد كه تعداد مضارب 5و7 را در بازه 231~846 چاپ كند.

Begin
K:=0;
C:=0;
For i:=846 downto 231 do
Begin
If I mod 5 = 0 then
C:=c+1;
If I mod 7 = 0 then
K:=k+1;
End;
Writeln('5=',c,'7=',k);
End;
End.

مثال : برنامه اي بنويسيد كه حقوق پايه وتعداد فرزندان 100 كارگر را از ورودي دريافت و مبلغ حقوق آنها را بر اساس فرمول زير حساب كند0
1000*تعداد فرزند + حقوق پايه = حقوق كل


Begin
For i:=1 to 100 do
Begin
Writeln('enter salary and number of children');
readln(salary,num);
kol := salary + num * 1000;
writeln(kol);
end;
end.


مثال : برنامه اي بنويسيد كه 100 عدد را از ورودي دريافت و ميانگين و حاصلجمع آنها را به ما بدهد.

Begin
Sum:=0;
For i:= 1 to 100 do
Begin
Writeln('enter num');
Readln(num);
Sum:=sum+num;
End;
Ave:=ave/100;
Writeln(sum,ave);
End.




تعداد تكرار نامعين :
Do شرط while
begin
___
___
___
end;
مثال : برنامه اي بنويسيد كه اعداد 100..1 را چاپ كند

Begin
I:=1;
While i<=100 do
Begin
Write(i);
I:=i+1;
End;

مثال : برنامه اي بنويسيد كه تعدادي اسم را از ورودي دريافت و به ما بگويد چند بار اسم ali تكرار شده است(آخرين اسم end است).

Var
S:integer;
St:string;
Begin
Read(st);
While st<> 'end' do
Begin
If st='ali' then
S:=s+1;
Read(st);
End;write(s);
End.


مثال : برنامه اي بنويسيد كه تعدادي عدد كه آخرين آنها صفر است را از ورودي دريافت و حاصلجمع آنها را چاپ كند.

Begin
Readln(num);
T:=1;
While num<>0 do
Begin
Sum:=sum+num;
Readln(num);
T:=t+1;
End;
Writeln('s=',s,'average',s/t);
End;

تكليف : براي دانش آموزان يك كلاس برنامه اي بنويسيد كه نام آنها به همراه تعداد نمرات و سپس نمرات آنها را به فرم زير از ورودي دريافت كند.تعداد دانش آموزان كلاس نامعين است ولي آخرين نفر نامش end است .برنامه ميبايستي پس از دريافت هر يك از اطلاعات پيامي به شكل زير چاپ كند.

Average: Sum: Ali Name:
3
18
20
13.5


program test;
var
name:string[10];
ave,sum,nomreh:real;
num,i:integer;
begin
writeln('enter name ' );
readln(name);
while name <> 'end' do
begin
writeln('enter num:');
readln(num);
for i:=1 to num do
begin
writeln('enter nomreh: ');
readln(nomreh);
sum:=sum+nomreh;
end;
ave:=sum/num;
writeln('name:',name,'sum:',sum,'ave:',ave);
writeln('enter name ');
readln(name);
end;
end.


تكليف : ميخواهيم براي برنامه هاي خود يك منو تهيه كنيم اين منو شامل موارد زير است
1) load
2) save
3) edit
4) exit
please select a number :


program test;
var
num:integer;
begin
writeln(' 1) load');
writeln(' 2) save');
writeln(' 3) edit');
writeln(' 4) exit');
writeln(please select a number : ');
readln(num);
while num<>4 do
begin
case num of
1:writeln('loading');
2:writeln('saving');
3:writeln('editing');
end;
end;
end.

WooKMaN
23-11-2005, 08:25
آموزش پاسکال قسمت سوم


مثال : برنامه اي بنويسيد كه دو عدد را از ورودي دريافت و طبق جدول زير نسبت به مقدار آن واكنش نشان دهد

3 2 1 a
B+...+3+2+1 1..b b..1 واكنش


Begin
Writeln (' enter a,b :');
Readln(a,b);
Case a of
1:begin
for i:=1 to b do
write(i);
end;
2:begin
or I;=b downto 1 do
write(i);
end;
3:begin
sum:=0;
for i:=1 to b do
sum:=sum+I;
write(sum);
end;
end.

آرايه ها :
آرايه ها به عناصري اتلاق ميشود كه با يك نام تعدادي محل از حافظه را كنترل كند براي تشخيص محلها از انديس استفاده ميشود
انواع آرايه ها :
1- آرايه هاي يك بعدي
2- عناصر دو بعدي
3- آرايه هاي سه بعدي

تعريف آرايه ها :
var
نوع of ]انديس پايان..انديس شروع: array [ نام آرايه
نوع متغير آرايه : متغير آرايه
خواندن آرايه :
مثال : برنامه اي بنويسيد كه نمرات 100 دانش آموز را از ورودي دريافت و در يك آرايه بريزد.

Var
A:array[1..100] of real;
Begin
For i:=1 to 100 do
Readln(a[i]);


مثال : برنامه اي بنويسيد كه نمرات 100 دانش آموز را از ورودي دريافت و 50 تاي اول را چاپ كند سپس تعداد نمرات 20 را مشخص كند.

Var
A:array[1..100] of real;
Begin
For I;=1 to 100 do
Writeln('enter no(',I,')');
Readln(a[i]);
For i:=1 to 50 do
Writeln(a[i]);
S:=0;
For i:=1 to 100 do
If i:=1 to 100 do
If a[i]=20 then
S:=s+1;
Writeln(s);
End.

پيدا كردن max,min
عنصر اول =min
حلقه براي گردش در آرايه
Min < عنصر فعلي if
عنصر فعلي min :=
Write(min);
مثال : برنامه اي بنويسيد كه با دريافت نمرات 100 دانش آموز بالاترين و پايين ترين نمره را در بين اين 100 نفر پيدا كند.

Var
A:array[1..100] of real;
I:integer;
Begin
For i:=1 to 100 do
Readln(a[i]);
Min:=a[1];
Max:=a[1];
For i:=2 to 100 do
Begin
If a[1]< min then
Min:=a[i];
If a[i]>max then
Max := a[i];
End;
Writeln('max is :',max,'min is :',min);
End.

مثال : برنامه اي بنويسيد كه با دريافت 100 اسم به ما بگويد تعداد تكرار اسم ali چند بار است وآيا اسم hassan بيشتر ذكر شده يا اسم reza ؟

Var
A:array [1..100] of string;
Begin
For i:=1 to 100 do
Readln(a[i]);
Ali:=0;
Reza:=0;
Hassan:=0;
For i:=1 to 100 do
Begin
If a[i]='ali' then
Ali:=ali+1;
If a[i]='reza' then
Reza:=reza+1;
If a[i]='hassan' then
Hassan:=hassan+1;
Endd
Writeln(ali is :',ali);
If reza>hassan then
Writeln('reza')
Else
Writeln('hassan');
End.

مثال : برنامه اي بنويسيد كه با دريافت نام و نمره 100 دانش آموز تنبل ترين فرد كلاس را مشخص كند.

Var
Name:array[1..100] of string;
No:array[1..100] of real;
Begin
For i:=1 to 100 do
Begin
Readln(name[i]);
Readln(no[i]);
End;
Min:=no[1];
Namemin:=name[1];
For i:=2 to 100 do begin
If no[i] Begin
Min:=no[i];
Namemin:=name[i];
Writeln(namemin);
End.

آرايه هاي دو بعدي:
وقتي از آرايه دوبعدي استفاده ميكنيم بايد از دو حقه for استفاده كنيم.
مثال : برنامه اي بنويسيد كه نمرات 4 كلاس كه هر يك 20 دانش آموز دارد را از ورودي دريافت وتنبل ترين فرد را در اين 4 كلاس مشخص كند.

Var
A:array[1..20,1..4] of real;
Begin
For i:=1 to 4 do
Begin
For j:=1 to 20 do
Readln(a[j,i]);
End;
Min:=a[1,1];
For i:=1 to 4 do
For j:=1 to 20 do
If a[j,i]< min then
Min:=a[j,i];
Writeln(min);
End.

مثال : در يك آرايه 100*20دوهزار كاراكتر نگهداري ميشود برنامه اي بنويسيد كه تعداد تكرار حرف A را با a مقايسه كند و همچنين به ما بگويد آيا كاراكتر z در اين ماتريس وجود دارد ؟

Var
A:array[1..20,1..100] of character;
Bool:Boolean;
B,b1:integer;
Begin
For i:=1 to 100 do
For j:=1 to 20 do
If a[I,j]='A' then
B:=b+1;
If a[I,j]='a' then
B1:=b1+1;
If a[I,j]='z' then
Bool:=true;
End;
If b>b1 then writeln('A>a');
If b If b=b1 then writeln('A=a');
If true then writeln('''z''exist');
End.


تكليف : ميخواهيم نام و نمره تعدادي دانش آموز يك كلاس را از ورودي دريافت كنيم و مشخص كنيم كه تنبل ترين و زرنگ ترين فرد كلاس كيست.چند نفر نمره زير 10 گرفتند؟نام كساني كه نمره آنها در بازه 17 تا 15 مي باشد ب همراه نمره آنها چاپ شود آخرين نفر نامش end است حداكثر تعداد دانش آموزان 100 نفر است.

Var

a:array [1..100] of string ;
b:array[1..100] of real;
begin
i:=1;
read(a[i]);
while a[i]<>'end' do begin
readln(b[i]);
i:=i+1;
readln(a[i]);
end;
j:=i-1;
min:=a[1];
max:=a[1];
for i:= 2 to j do
begin
if b[i] >max then
begin
max:=b[i];
name:a[i];
end;
end
writeln(name);
count:=0;
for i:=1 to j do
if b[i]<=10 then
count:=count+1;
writeln(count);
for i:=1 to j do
if (b[i]<17) and (b[i]>15) then
write(b[i],a[i]);
end.

تكليف : برنامه اي بنويسيد كه حاصل اين عبارت را حساب كند.
i/i!=1/1!+2/2!+3/3!+4/4!+5/5!
N!= 1*2*3*4*…*n

Begin
Sum:=0;
For n:=1 to 5 do
Begin
For m:=1 to n do
F:=f*m;
Sum:=sum+n/f;
End;
Writeln(sum);
End.

تكليف : برنامه اي بنويسيد كه نمرات 80 دانش آموز را كه در چهار كلاس دسته بنده شده اند را از ورودي دريافت كند سپس به سوالات زير جواب دهد.
1- معدل هر يك از كلاسها
2- نمره تنبل ترين و زرنگترين شخص در هر كلاس به طور جداگانه

Var
A:array [1..4,1..20] of real;
Begin
For i:=1 to 4 do
For j:=1 to 20 do
Begin
Writeln('please enter nomreh');
Readln(a[I,j]);
End;
For i:=1 to 4 do
Begin
Sum:=0 ;
For j:=1 to 20 do
Begin
Sum:=a[I,j]+sum;
End;
Writeln(sum/20,'average of this class');
End;
For i:=1 to 4 do
Begin
Max :=a[1,1];
Min:=a[1,1];
For j:=2 to 20 do
Begin
If a[I,j]>max then
Max :=a[I,j];
End;
Writeln(I,min,max);
End;
End.

- String :
String آرايه اي از كاراكترهاست .اغلب لازم است كاراكترهايي در رشته موجود درج شوندو يا كاراكترهايي به جاي بخشي از رشته نوشته شوند , زيررشته اي در رشته جستجو گردد و يا دو رشته با هم الحاق شوند.
رشته تهي : طول رشته ثابت نيست و با داداه هايي كه در آن ذخيره شده است مشخص مي گردد.كاراكترهايي كه در رشته قرار مي گيرد از حداكثر طولي كه براي آن تعيين ميشود بيشتر نخواهد بود. اگر name رشته كاراكتري باشد دستور زير name را به رشته تهي تبديل ميكند:

Name:='';

تبديل رشته به اعداد :
در پاسكال زير برنامه هايي وجود دارند كه به آساني ميتوانند رشته ها را پردازش كنند. زيربرنامه val رشته عددي را گرفته به مقدار عددي تبديل ميكند.
رشته عددي رشته اي است كه حاوي كاراترهاي '0' تا '9' و نقطه مميز باشد مثل '12.5' و'13.5' زيربرنامه val به صورت زير به كار ميرود.

Val (st,number,error)

St رشته اي است كه بايد به عدد تبديل شود و number متغيري است كه رشته تبديل شده به عدد در آن قرار ميگيرد. چنانچه در رشته st كاراكتر نا معتبري (كاراكترهاي غير از( '0' تا '9' و'.' ) , محل وجود آن كاراكتر در پارامتر error قرار ميگيرد. اگر error برابر با صفر باشد معنايش اينست كه كاراكتر نا معتبري وجود ندارد. اگر number از نوع صحيح باشد st به مقدار صحيح و اگر number از نوع اعشاري باشد st به مقدار اعشاري تبديل ميشود .
مثال زير را در نظر بگيريد:

Var st :string;
Num,e:integer;
St:='352';
Val (st,num,e);

مقدار 352 در متغير num ومقدار صفر در متغير e قرار ميگيرد اكنون دستورات زير را در نظر بگيريد :

St:='35#'2;
Val (st,num,e);

با اجراي دستور val به دليل وجود كاراكتر' # ' كه كاراكتر نامعتبري در اعداد است عدد 2 در متغير e قرار ميگيرد و معنايش اينست كه كاراكتر شماره 2 ( شماره گذاري از صفر شروع ميشود) نامعتبر است و عمل تبديل صورت نميگيرد و مقدار num تعريف نشده است.
تبديل عدد به رشته :
براي تبديل مقدار عددي به رشته عددي از زيربرنامهstr استفادهميشود و به صورت زير به كار ميرود:

Str (number : format,numstring)

با اين دستور مقداري كه در number قرار دارد به رشته اي به طول format تبديل ميشود و در رشته numstring قرار ميگيرد . دستورات زير را در نظر بگيريد:

Var x:integer;
St:string;
X=352;
Str(x:5,st);

با اجراي اين دستور مقدار 352 به رشته '352' تبديل شده در st قرار ميگيرد

WooKMaN
23-11-2005, 08:25
آموزش پاسکال قسمت چهارم


دستورات زير را در نظر بگيريد:


Var y1,y2:real;
St1,st2 : string;
Y1:=352.768
Y2:=476.395
Str(y1:7:2,st1);
Str(y2:3:1,st2);

با اجراي دستور str اول مقدار 352.768 به رشته '352.768' تبديل ميشود و در st1 قرار ميگيرد و با اجراي دستورstr دوم مقدار 476.395 به رشته '476.395'تبديل ميشود و در st2 قرار ميگيرد.
جدا كردن زيررشته اي از رشته:
زيررشته بخشي از رشته است و براي جدا كردن زيررشته از رشته از تابع copy استفاده ميشودتابع copy به صورت زير به كار ميرود.

Copy (source,index,size)
S:='I am learning pascal ';
S1:=copy(s,15,6);

دستور copy باعث ميگردد تا با شروع از محل 15 تعداد 6 كاراكتر از رشته s استخراج شود و در s1 قرار گيرد. بنابراين محتويات رشته s1 برابر است با 'pascal'.
الحاق رشته ها :
منظور از الحاق رشته ها اتصال رشته ها به يكديگر است به عنوان مثال اگرs1:='ab' و s2:='cde' الحاق دو رشته (s1,s2) به صورت 'abcde' خواهد بود براي الحاق رشته ها از تابع concat استفاده ميشود:
(اسامي رشته ها)concat
دستورات زير را در نظر بگيريد:

S1:='pascal';
S2:='is a ;
S3:='language';
S4:=concat(s1,s2,s3);

با اجراي اين دستور s3 به انتهاي s2 متصل ميشود و رشته نتيجه به انتهاي s1 متصل ميگردد و در نتيجه رشته s4 عبارت است از'pascal is a language': . اگر طول رشته حاصل بيش از 255 باشد بقيه كاراكترها حذف ميشوند.
جستجوي رشته اي در رشته ديگر:
براي اين كار از تابع pos استفاده ميشود كاربرذ اين تابع به صورت زير است:

Pos(s1,s2)

S1 رشته اي است كه بايد در s2 وجود داشته باشد محل اولين وقوع آن برگردانده ميشود و گر نه مقدار صفر برگردانده ميشود دستورات زير را در نظر بگيريد:

S1:='learning'
S2:='I am learning pascal';
S3:='english'
X:=pos(s1,s2)
y:=pos(s3,s2)

چون رشته s1 در s2 وجود دارد دستور pos اول مقدار 6 را در x قرار ميدهد و معنايش اين است كه رشته 'learning' در محل 6 رشته s2 وجود ندارد مقدار صفر در y قرار ميگيرد.
محاسبه طول رشته :
براي محاسبه طول رشته از تابع length به صورت زير استفاده ميشود:
(رشته)length
دستورات زير را در نظر بگيريد:

S1:='xymn'
X:=length(s1)

چون طول رشته s1 برابر 4 است مقدار x برابر 4 خواهد بود.
حذف و درج زيررشته:
زير رشته اي را ميتوان از رشته اي حذف كرد و يا زيررشته اي را ميتوان در رشته اي درج كرد براي حذف زير رشته از زيربرنامه ها به صورت زير به كار ميروند:

Delete(source,index,size)
Insert(pattern,destination,index)

در زيربرنامه delete زيررشته اي به طول size با شروع از محل index از رشته source حذف ميشود و در زيربرنامه insert زيررشته pattern با شروع از محل index در رشته destination درج ميشوددستورات زير را در نظر بگيريد:

S1:=pas***cal
Delete(s1,4,3)
S2:='paal';
S3:='sc';
Insert(s3,s2,);

دستور delete باعث ميشود تا با شروع از محل 4 رشته s1 حذف شده و رشته s1 به pascalتبديل شود دستور insert موجب ميشود تا رشته s3 در s2 درج شود و در نتيجه رشته s2 به 'pascal' تبديل شود.
مثال : برنامه اي بنويسيد كه يك اسم را از ورودي دريافت و آنرا بر عكس چاپ كند

Readln(name);
For i:=length(name) downto 1 do
Write (name[i])

مثال : برنامه اي بنويسيد كه كه يك نام را از ورودي دريافت و به ما بگويد كه آيا اين نام با حرف a شروع ميشود يا خير؟

Readln(name);
If name[1]='a' then
Writeln('ok')
Else
Writeln('not ok');

مثال : برنامه اي بنويسيد كه يك نام را از ورودي دريافت و حروف آنرا يك در ميان چاپ كند.

Readln(name);
For i:=1 to length(name) do
If I mod 2 = 0 then
Writeln(name[i]);


روش ديگر:"
For i:=1 to int(length(name)/2) do
Writeln(name[i*2]);

مثال : برنامه اي بنويسيد كه يك رشته را از ورودي دريافت و متقارن بودن آنرا چك كند.
1 2 3 4 5 5 4 3 2 1

var
N:string;
Begin
Readln(n);
For i:=1 to int(length(n)/2) do
Begin
If n[i] <> n[length(n)-i+1] then
K:=0;
End;
If k=1 then
Writeln ('ok')
Else
Writeln('no');
End.

مثال : برنامه اي بنويسيد كه تعداد حروف a موجود در يك رشته ورودي را بشمارد.

Var st:string;
Begin
Readln(st);
C:=0;
For i:=1 to length(st) do
If st[i]='a' then ?if st[i] in ['a','A'] then
C:=c+1;
Writeln(c)

مثال : برنامه اي بنويسيد كه تعداد اسامي alireza موجود در رشته را بشمارد.

Begin
Readln(st);
C:=0;
While pos('alireza',st) <> 0 do
Begin
C:=c+1;
J:=pos('alireza',st);
Delete(st,pos('ali',st),3);
End;
Write ( c );
End.

مثال : برنامه اي بنويسيد كه دو رشته را از ورودي دريافت و بعد از كاراكترمساوي كه در رشته اول وجود دارد رشته دوم را چاپ كند.

Readln(st,st1);
J:=pos('=',st);
Writeln(copy ((st,1 j) , st1, copy (st,j+1,100));


تكليف : برنامه اي بنويسيد كه با دريافت سه حرف و قرار دادن آنها در يك آرايه سه تايي كليه تركيبات ممكن را كه سه حرف تركيباتشان به هم نخورد چاپ كند.
W a x
A x w
W a x
مثال : برنامه اي بنويسيد كه يك رشته را از ورودي دريافت و كليه كلمات موجود در آن را بشمارد.

Readln(st);
S:=0;
St:=st+' '
While pos(' ',st) <> 0 do
Begin
S;=s+1;
Delete(st,1,pos(' ',st));
While st[1]=' 'do
Delet (st,1,1);
End;
End.

تكليف : برنامه اي بنويسيد كه 100 رسته را از ورودي دريافت و در يك آرايه به طول 100 از نوع string بريزيد و به سؤالات زير جواب دهد.
1- تعداد كل كلمات
1- تعداد كل حروف
2- تعداد حروف صدا دار

ذخيره اطلاعات :
Log file : فايلي است كه تمام تغييرات مربوط به يك محيط را ثبت ميكند
فايلها :
1- متني text
2- ركوردي typed
3-بدون نوع
4-untyped

معرفي فايلهاي متني :
Var

Text : نام فايل

نسبت دادن فايل :

; ('نام خارجي ,'نام فايل ) assign

مثال :

Assign(f,'c:\a1.dat.ddd');

باز كردن جهت خواندن

;( نام فايل)reset

باز كردن جهت نوشتن

; ( نام فايل)rewrite
) ___,نام فايل)readln
) ___,نام فايل)writeln
) نام فايل)close

تا close انجام نشود data ذخيره نميشود .
نكته بسيار مهم : در هر يك از مسائلي كه در مورد فايلها مطرح ميشود مي بايستي به نحوي از يكي از تكنيكهاي نگهداري اطلاعات در حافظه اصلي استفاده نمود اين تكنيكها ممكن است استفاده از متغيرها و آرايه ها و ماتريسها و ودرختهاو...استفاده نمود ولي تنها با دو عمل خواندن و نوشتن به روي فايل كار انجام ميشود
Update : ميخوانيم ولي دوباره ميريزيم سر جاش
Append : بهش يك چيزي اضافه ميكنيم
نكته : عمل rewrite باعث ميگردد چنانچه فايل وجود نداشته باشد ايجاد و چنانچه وجود دارد اطلاعاتش به طور كامل پاك شود.
مثال : برنامه اي بنويسيد كه100 اسم را از ورودي دريافت و آنها را در يك فايل به نام a1.dat))بنويسد.

Var
F:text;a:string;
Begin
Assign(f,'a1.dat');
Rewrite(f);
For i:=1 to 100 do
Readln(a);
Writeln(f,a);
End;
Close(f);
End.

مثال : برنامه اي بنويسيد كه فايل a1.dat را خوانده و به ما بگويد چند بار اسم ali تكرار شده است؟

Var
A:text;
B:string;
Begin
Assign(a,'a1.dat');
Reset(a);
Sum:=0;
For i:=1 to 00 do
Begin
Readln(a,b);
If b='ali' then
Sum:=sum+1;
End;
Close(a,b);
End;

مثال : برنامه اي بنويسيد كه تعدادي اسم را كه آخرين آنها end است از ورودي دريافت و در يك فايل به نام aa.dat بريزد آنگاه فايل را بسته و قسمتهاي زير را به طور جداگانه انجام دهد.
1- تعداد حسنها بيستر است يا علي ها
2- چند اسم وجود دارد كه با حرف z شروع ميشود.


Var
f:text;
Name:string;
Begin
Assign(f,'aa.dat');
Rewrite(f);
Readln(name);
While name<> 'end' do
Begin
Writeln(f,name);
Readln(name);
End;
Close(f);
H:=1;
A:=1;
Z:=1;
Reset(f);
While not eof (f) do
Begin
Readln(f,name);
If name='ali' then
A:=a+1;
If name ='hassan' then
H:=h+1;
End;
Close(a);
If h>a then writeln('h>a');
If h If h=a then writeln('h=a');
End;
Close(f);
Reset(f);
While not eof (f) do
Begin
Readln(f,name);
If name[i]='z' then
Z;=z+1;
End;
Close(f);
Writeln('sum of z is :'z);
End.

تكليف : برنامه اي بنويسيد كه تعدادي نام را از ورودي دريافت و در يك فايل بريزد سپس فايل تشكيل شده را باز كرده و از روي اين فايل دو فايل ديگر تشكيل دهيد كه در يكي از آنها اسامي كه بين a تا z قرار گرفته اند ريخته و در فايل دوم كليه اسامي كه از v تا z هستند را بريزد.

Program test;
Var
Name : string;
F,f1,f2:text;
Begin
Assign(f,'a.dat');
Rewrite(f);
Writeln('enter a name ');
Readln(name);
While length(name)>0 do
Begin
Writeln(f,name);
Writeln('enter a name');
Readln(name);
End;
Close(f);
Reset(f);
Assign(f1,'a1.dat');
Assign(f2,'a2.dat');
Rewrite(f1);
Rewrite(f2);
While not eof (f) do
begin
Readln(f,name);
Case name[1] of
'a'..'u':writeln(f1,name);
'v'..'z':writeln(f2,name);
end;
end;
close(f2);
close(f1);
close(f);
end.

تكليف : برنامه اي بنويسيد كه نام دو فايل را از ورودي دريافت و از اطلاعات داخل اين دو فايل فايل سومي تشكيل دهد كه حاصل تركيب دو فايل قبل باشد.

var
h,f,g:text;
a:string;
begin

writeln('enter first filename') ;
readln(a);
assign(h,a);
writeln('enter second filename') ;
readln(a);
assign(f,a);
reset(h);
reset(f);
assign(g,'out.dat');
rewrite(g);
while not eof(h) do
begin
readln(h,a);
writeln(g,a);
end;
while not eof(f) do
begin
readln(f,a);
writeln(g,a);
end;
close(f);
close(h);
close(g);
End.

تكليف :برنامه اي بنويسيد كه در ضمن عمل merge دو فايل مرتب شده را با يكديگر تركيب و يك فايل مرتب شده به دست آوريم.

WooKMaN
26-11-2005, 08:43
سلام دوستان بگيد آموزش چي مي خوايد تا منم واستون اينجا بذارم

WooKMaN
29-11-2005, 08:49
سلام دوستان بگيد آموزش چي ميخوايد تا من واستون پيدا كنم !

Amir_P30
30-11-2005, 03:15
با سلام

دوست عزيز لازم ميدونم مراتب تشكر خودمو به شما عرض كنم .
خيلي عالي خيلي خوب خيلي جامع

به نظر من اگه براتون ممكنه آموزش جامع ساير زبان هاي برنامه نويسي و يا نرم افزارهايي كه بچه ها در تاپيك درخواست مقالات مينويسن رو بنويسين.

ممنون

WooKMaN
30-11-2005, 23:02
امير جان روي چشم !

Kolubive
02-12-2005, 07:05
با سلام

نیش نیش جان اگه برات مقدور باشه و در صورت اتمام کارت , یه فایل پی دی اف از آموزشات تهیه کن که یادگاری داشته باشیم

با تشکر

WooKMaN
02-12-2005, 15:15
مي خوام E-book واسشون درست كنم
اينطور بهتره

Kolubive
03-12-2005, 02:33
اگه اینطور باشه که عالیه

راستی کار آموزش تموم شده یا ادامه هم داره

اگه تموم شده , بیصبرانه منتظر ایبوک هستم

با تشکر

WooKMaN
10-12-2005, 23:37
دوستان الان به خاطر يه سري از مسايل يه كم سرم شلوغه
در اولين فرصت تمام آموزش ها رو يا بصورتpdf و يا بصورت e-book درست مي كنم

Kolubive
11-12-2005, 01:15
سلام

هر موقع وقت کردی

عجله ای نیست

با تشکر

sensor
12-12-2005, 12:17
سلام دوستان من همون نيش نيش هستم
مثل اينكه مدير تالار آي دي منو به حالت تعليق در آورده
دليلش رو هم خودم نمي دونم
ممنون مي شم توضيح بده چرا اين كارو كرده !
راستي مدير تالار كيييييييه ؟

WooKMaN
12-12-2005, 13:33
سلام دوستان
آي ديم غير فعال شده بود
نمي دونم چرا !
ولي دوباره فعال شد

WooKMaN
05-01-2006, 22:26
سلام به شما عزيزان
خوشحالم ميشم بگيد آموزش چي ميخوايد تا اگه پيدا كردم واستون بذارم !