ایران سرفراز- نرم افزار وپروژهای دانشجویی


نرم افزار وپروژهای دانشجویی

فصل نهم ساختارها در# C

<!-- /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman";} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:35.4pt; mso-footer-margin:35.4pt; mso-paper-source:0;} div.Section1 {page:Section1;} -->

فصل نهم

C # ساختارها در

آنچه که در این فصل یاد خواهید گرفت::

با ساختار و ویژگیهای آن

نحوهی ایجاد ساختارها و آشنایی با خصوصیات نوعمقداری بودن آن

ساختار 1 یک نوع داده تعریف شده کاربری اس ت . ساختارها شبیه کلا س ها هستند . آنها ممکن است سازند ه ها، خصوصیات،

متدها، فیلدها، عملگرها، انواع دادهی تودرتو و اندیسگذارها را شامل شوند.

تفاوت های مهمی مابین کلاس و ساختار وجود دار د . برای مثال، ساختارها وراث ت یا مخر ب ها را پشتیبانی نم ی کنند . مهمتر

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

اشیائی که مفهوم ارجاع را نیاز ندارد مفید هستند.

هستند بکار #C دید اجماع این است که شما باید ساختارها را فقط برای انواع داد ه ی که کوچک، ساده و مشابه انواع داخلی

برید.

یک ساختار دقیقاً شبیه یک کلاس است، ++C اس ت. در ++C خیلی متفاوت از توجه کنن د: معنی ساختار ++C برنام هنویسان

اس ت. در public و در ساختار private با استثناء میدان دید که به طور پی شفرض متفاوت هستن د. در کلاس پیش فرض

محدودیتهایی دارند که در این فصل بحث خواهند شد. C # ساختارها انواع دادهی مقداری هستند. ساختارهای C #

ساختارها در آرای ه ها مؤثرتر عمل م ی کنند. با این وجود، در هنگام استفاده با کلکسیو ن ها کارایی کمتری دارن د . کلکسیونها

اشیاء را به صورت ارجاعی انتظار م ی روند و ساختارها باید جعب ه بندی شوند . جعبه بندی و از جعبه در آوردن عملیات سربار

هستند. پس کلا سها در کلسکسیو نها بهتر کار می کنند.

1 Struct

Mohsen_mahyar@yahoo.com

144

در این فصل نحو ه ی تعریف، کار با ساختارها و نحوهی مقداردهی اولیه مقادیر آنها با استفاده از سازند ه ها را یاد خواهید

گرفت.

-1-9 تعریف ساختارها

نحوهی اعلان یک ساختار تقریباً شبیه کلاس است.

[attributes] [access-modifiers] struct identifier [:interface-list] { structmembers

}

یک نقطه روی یک سطح دوبعدی را نشان م ی دهد. توجه کنید Loaction . 1 تعریف یک ساختار را نشان م ی دهد - مثال 9

struct از class دقیقا شبیه یک کلاس اعلان م ی شود، به استثناء اینکه به جای کلم ه ی کلیدی Location که ساختار

دو عدد صحیح را گرفته و مقدار آنها را به اعضای نمونه Location استفاده شده اس ت . همچنین توجه کنید که سازن د ه

به صورت خصوصیات اعلان می شوند. Location در x,y انتساب می دهد. مختصات yVal و xVal

1- مثال 9

#region Using directives

using System;

using System.Collections.Generic;

using System.Text;

#endregion

namespace CreatingAStruct

{

public struct Location

{

private int xVal;

private int yVal;

public Location( int xCoordinate, int yCoordinate )

{

xVal = xCoordinate;

yVal = yCoordinate;

}

public int x

{

get

{

return xVal;

}

set

{

xVal = value;

}

}

public int y

{

get

{

return yVal;

}

set

{

yVal = value;

}

}

public override string ToString( )

{

return ( String.Format( "{٠}, {١}", xVal, yVal ) );

}

}

public class Tester

فصل نهم-ساختارها

145

{

public void myFunc( Location loc )

{

loc.x = ۵٠;

loc.y = ١٠٠;

Console.WriteLine( "In MyFunc loc: {٠}", loc );

}

static void Main( )

{

Location loc١ = new Location( ٢٠٠, ٣٠٠ );

Console.WriteLine( "Loc١ location: {٠}", loc١ );

Tester t = new Tester( );

t.myFunc( loc١ );

Console.WriteLine( "Loc١ location: {٠}", loc١ );

}

}

}

Output:

Loc١ location: ٢٠٠, ٣٠٠

In MyFunc loc: ۵٠, ١٠٠

Loc١ location: ٢٠٠, ٣٠٠

مشتق می شوند، اما نمی توانند از کلاس یا Object برخلاف کلاس ها، ساختارها از ار ث بری پشتیبانی نم یکنند. آنها قطعاً از

ساختار دیگری ار ث بری کنند . ساختارها قطعاً مهر شده هستن د . شبیه کلاس ها، ساختارها م ی توانند چند واسط را پیاد ه سازی

کنند. تفاوت های دیگر کلاس و ساختار به صورت زیر هستند.

ساختار سازنده پیش فرض یا مخرب ندارد.

ساختارها مخرب ندارن د . نمی توانند یک سازند ه ی بدون پارامتر سفارشی داشته باشن د . اگر ساختار سازنده نداشته

شی ساختار را مقداردهی اولیه خواهد کر د . اگر شما یک سازند ه ی غیر پی ش فرض فرا ه م کنید، CLR ، باشد

اتفاق نخواهد افتاد و همه فیلدها به طور صریح مقداردهی اولیه می شوند. CLR مقداردهی اولیه توسط

بدون مقداردهی اولیه

نمی توانید یک فیلد از یک ساختار را مقداردهی اولیه کنید. پس دستور زیر غیر مجاز هستند.

private int xVal = ۵٠;

private int yVal = ١٠٠;

پنهان کردن داده و کپسوله private ساختارها طوری طراحی م ی شوند که ساده و سبک باشن د . در حالیکه داد ه های عضو

کردن را ترقی م ی دهند. بعضی برنامه نویسان احساس م ی کنند این ایده برای ساختارها ضایع کننده اس ت . آنها اعضای داده را

کرده و پیاد ه سازی ساختار را ساد ه می کنند. برنامه نویسانی دیگر احساس م ی کنند که خصوصیات، واسط ساده و public

واضح فراهم م ی کنند و برنام ه نویسی خوب، پنهان کردن داده را حتی با اشیاء سبک وزن پیشنهاد م ی کند . با توانای ی های

جایگزین کر د . کافی private را با متغیرهای public متغیرهای ،public 2005 ، می توان به کمک خصوصیات VS جدید

شما را به public متغیر VS . را اجرا کنید Refactor Encapsulate Field است روی متغیر کلیک راست کرده و

را ایجاد می کند. set و get تبدیل کرده و معاو نهای private

-2-9 ایجاد ساختارها

در ی ک دستور انتساب همانند یک نمونه از کلاس ایجاد کنی د . در new یک نمونه از یک ساختار را با استفاده کلم ه ی کلیدی

را به صورت زیر ایجاد م یکند: Location یک نمونه از Tester 1، کلاس - مثال 9

Location loc١ = new Location(٢٠٠،٣٠٠);

Mohsen_mahyar@yahoo.com

146

نامگذاری شده و دو مقدار 200 و 300 به آن رد می شوند. locl در اینجا نمونه جدید

-1 ساختارها به صورت انواع دادة مقداری -2 -9

با مقادیر 200 و 300 را ایجاد کرده اس ت . locl را شامل اس ت . ساختار Location 1 یک شی - مثال 8 Tester تعریف کلاس

را فراخوانی م یکند. Location این خط از کد سازنده

Location loc١ = new Location(٢٠٠،٣٠٠);

فراخوانی می شود. ()WriteLine سپس

Console.WriteLine("Loc١ location: {٠}", loc١);

یک ساختار (نوع دادة مقداری) است. کامپایلر به طور Location یک ش ی را انتظار م ی رود. اما متأسفانه WritLine ( ) متد

روی ()ToString رد م ی شود . متد ( )WriteLine اتوماتیک ساختار را جعب ه بندی می کند و آن ش ی جعبه بندی شده به

ارث بری می کند. آن قادر است به چندریختی عکس العمل Object شی جعبه بندی شده فراخوانی م ی شود و چون ساختار از

کند. override نشان دهد و ممکن است هر متد را

Loc١ location: ٢٠٠, ٣٠٠

کرده override را ToString می توانید این جعب ه بندی را با تغییر تکه کد قبلی بصورت زیر اجتناب ک ن ید: در صورتی که

باشید.

Console.WriteLine("Loc١ location: {٠}",loc١.ToString());

ساختارها اشیاء مقداری هستند و زمان رد کردن به یک تابع، آنها بوسیله مقادیر رد م ی شوند. همانطور که در خط کد بعدی

رد می شود. ()myFunc به متد locl می بینید شی

t.myFunc(loc١);

انتساب داده می شوند و این مقادیر جدید در خروجی چاپ م یشوند: y,x مقادیر جدید به ()myFunc در

Loc١ location: ۵٠, ١٠٠

را فراخوانی کنید، مقادیر بدون تغییر هستند. WritLine( ) برگردید و (Main) زمانی که به تابع فراخوانی کننده

Locl Location: 200, 300

تغییر class ایجاد م ی شود. اعلان را به ()myFunc ساختار به صورت یک ش ی مقداری رد شده است و یک کپی از آن در

دهید:

public class Location

و آزمایش را مجدداً اجرا کنید. خروجی این است:

Loc١ location: ٢٠٠, ٣٠٠

In MyFunc loc: ۵٠, ١٠٠

Loc١ location: ۵٠, ١٠٠

،()Main تغییر یابد، هنگام برگشت به ()myFunc مفهوم ارجا ع ها را دار د . پس زمانی که مقادیر آن در Location حالا شی

شی اصلی نیز تغییر داده م یشود.

new -2 ایجاد ساختارها بدون -2 -9

new 1 زمانی که عملگر - ایجاد م ی شود. پس در مث  ال 9 Stack یک ساختار (نه یک کلا س ) است، آن روی locl چون

فراخوانی می شود.

فصل نهم-ساختارها

147

Location loc١ = new Location(٢٠٠،٣٠٠);

را فراخوانی م ی کند . با این Location سازنده new منتج شده، در روی پشته ایجاد م ی شود. عملگرد Location شی

سازگار #C امکان پذیر است. این عمل با متغیرهای درونی new وجود، بر خلاف یک کلاس، ایجاد یک ساختار بدون استفاده از

2 را مشاهده کنید. - است. مثال 8

2- مثال 8

#region Using directives

using System;

using System.Collections.Generic;

using System.Text;

#endregion

namespace StructWithoutNew

{

public struct Location

{

public int xVal;

public int yVal;

public Location( int xCoordinate, int yCoordinate )

{

xVal = xCoordinate;

yVal = yCoordinate;

}

public int x

{

get

{

return xVal;

}

set

{

xVal = value;

}

}

public int y

{

get

{

return yVal;

}

set

{

yVal = value;

}

}

public override string ToString( )

{

return ( String.Format( "{٠}, {١}", xVal, yVal ) );

}

}

public class Tester

{

static void Main( )

{

Location loc١; // no call to the constructor

loc١.xVal = ٧۵; // initialize the members

loc١.yVal = ٢٢۵;

Console.WriteLine( loc١ );

}

}

}

Mohsen_mahyar@yahoo.com

148

متغیرهای محلی را به طور مستقیم ، ()WriteLine و رد کردن این شی به locl 2 قبل از فراخوانی یک متد از - در مثال 8

مقداردهی اولیه کردید.

loc١.xVal = ٧۵;

loc١.yVal = ٢٢۵;

اگر در برنامهی خود یکی از دستورات را به توضیح تبدیل کرده و مجدداً کامپایل کنید.

static void Main()

{

Location loc١;

loc١.xVal = ٧۵;

// loc١.yVal = ٢٢۵;

Console.WriteLine(loc١);

}

یک خطای کامپایل به صورت زیر خواهید گرفت.

Use of unassigned local variable 'loc١'

به آنها دستیابی کنید. y,x زمانی که همه مقادیر را انتساب دهید، می توانید از طریق خصوصیات

static void Main()

{

Location loc١;

loc١.xVal = ٧۵; // assign member variable

loc١.yVal = ٢٢۵; // assign member variable

loc١.x = ٣٠٠; // use property

loc١.y = ۴٠٠; // use property

Console.WriteLine(loc١);

}

زمان استفاده از خصوصیات دقت کنی د . اگرچه کپسو له کردن فیلدهای خصوصی از طریق خصوصیات امکا ن پذیر اس ت . در

واقع خصوصیات، متدهای عضو هستند و تا زمانی که همة متغیرهای عضو را مقداردهی اولیه نکرده باشید، نم ی توانید یک

متد عضو را فراخوانی کنید.

-3-9 خلاصه

ساختار یک نوع داده تعریف شده کاربری است

هستند بکار برید. #C • ساختارها را فقط برای انواع دادهی که کوچک، ساده و مشابه انواع داخلی

ساختار نوعدادهی مقداری است، در حالیکه کلاس نوع دادهی ارجاعی است.

نیز میتوان عمل کرد. new • ایجاد یک نمونه از یک ساختار، شبیه کلاس است، اما بدون کلمهی کلیدی

در ساختارها نیز میتوان از پنهانسازی و کپسوله کردن دادهها استفاده کرد.

تبدیل کرد. یعنی اعضای ساختار public یک ساختار را به خصوصیات public • به راحتی میتوان فیلدهای

(Refactor Encapsulate Field باشند. (با کمک private

نمیتوان در تعریف ساختار از ارثبری استفاده کرد، ولی ساختار میتواند چندین واسط را پیادهسازی کند.

هنگام ارسال یک ساختار به تابع، یک کپی از آن به ساختار ارسال میشود.

کند. override را Object • ساختار میتواند متدهای کلاس

هنگام ارسال یک نمونه زا ساختار به متدهای کنسولی، آنها جعبهبندی میشوند.

در تعریف ساختار مقداردهی اولیه اعضای آن امکانپذیر نیست.

Mohsen_mahyar@yahoo.com

 

   + MOHSEN GHASEMI - ۸:٠٦ ‎ق.ظ ; ۱۳۸٩/٤/٩