ساختار (struct) چیست ( درمحیط سی شارپ و دات نت )؟
ساختار (struct) چیست؟
به بیانی ساده می توان گفت ساختار یک نوع مقداری(value type) است.نحوه تعریف و پیاده سازی آنها بسیار شبیه کلاس می باشد.اما تفاوتی بسیار مهم بین آن دو وجود دارد که باید به آن توجه نمود.همانطور که گفته شد ساختار یک نوع مقداری است، در حالی که کلاس ها انواع ارجاعی(reference types) هستند.انواع مقداری،مقادیرشان را در همان نقطه ای از حافظه که در آن تعریف شده اند ذخیره می کنند.اما انواع ارجاعی اشاره گری را به شیئی در حافظه نگهداری می نمایند.هنگامی که شما ساختاری را کپی می کنید، C# نسخه ای جدید از شیء را ایجاد می کند و آن را به نمونه ای از یک ساختار جدید نسبت می دهد.اما چنانچه شما در C#، کلاسی را کپی نمایید،در واقع یک نسخه کپی از ارجاع به شیء ایجاد می شود(نه نسخه ای از خود شیء)، و آن نسخه کپی به نمونه از یک کلاس دیگر نسبت داده می شود.تفاوت دیگری که بین آنه وجود دارد این است که ساختار ها بر خلاف کلاس ها destructor ندارند.همچنین در ساختار ها ما قادر به پیاده سازی ارثبری نمی باشیم.در عوض ارثبری واسط ها را می توان داشت.
در فریم ورک دات نت انواع بسیار زیادی وجود دارند که از نوع ساختار می باشند.بسیاری از انواع پیش ساخته (Built-in) از این قبیل هستند.بعنوان مثال System.int32 از نوع int، aSystem.Single از نوع float و System.Bool در C# از نوع bool هستند.در واقع می توان گفت انواع پیش ساخته در C# نام های مستعاری برای انواع .Net Framework می باشند.اگر شما به مستندات موجود در رابطه با هریک از این انواع .NET Framework نگاهی بیاندازید، می بینید که همه آنها از نوع ساختار تعریف و پیاده سازی شده اند.این مسئله اهمیت شناخت نوع ساختار را بیش از بیش مشخص می کند.
پیاده سازی یک ساختار:
اگر چه رفتار های بین کلاس ها و ساختار ها کاملا با یکدیگر متفاوت می باشند، اما پیاده سازی آنها به یکدیگر بسیار شبیه است.تنها تفاوت در استفاده از کلمه کلیدی Struct بجای Class می باشد.در مثال زیر چگونگی تعریف یک ساختار را مشاهده می کنید.در این مورد ساختار ما یک مستطیل با خاصیت های طول و عرض می باشد.
struct Rectangle { private int m_width; public int Width { get { return m_width; } set { m_width = value; } } private int m_height; public int Height { get { return m_height; } set { m_height = value; } } }
همانطور که می بینید تعریف این ساختار بسیار شبیه به یک کلاس می باشد، با این تفاوت که بجای کله کلیدی class در آن از struct استفاده شده است.
نحوه استفاده از ساختار (struct):
روش استفاده از یک ساختار مانند طریق استفاده از کلاس ها می باشد.به این صورت که ابتدا یک نمونه از آن را ایجاد کرده و سپس از آن استفاده می نماییم.در مثال زیر مشاهده خواهید کرد که چگونه ساختار مستطیلمان را نمونه سازی کرده و به خاصیت های آن دسترسی پیدا می کنیم.
using System;
class StructExample
{
static void Main()
{
Rectangle rect1 = new Rectangle();
rect1.Width = 1;
rect1.Height = 3;
Console.WriteLine(“rect1: {0}:{1}”, rect1.Width, rect1.Height);
Console.ReadKey();
}
}
همانطور که در مثال بالا مشاهده می فرمائید، تابع main() نمونه ای از ساختار Rectangle را ایجاد کرده و خاصیت های ارتفاع و عرض آن را مقدار دهی می نماید.این روش دقیقا همان روش دسترسی به خاصیت های یک کلاس می باشد.خروجی تکه کد بالا بصورت زیر خواهد بود.
rect1: 1:3
البته برای استفاده از یک ساختار روشی دیگر نیز وجود دارد که در زیر به شما نشان داده شده است:
// Object Initialization
Rectangle rect11 = new Rectangle
{
Width = 1,
Height = 3
};
تکه کد بالا ایجاد کننده شیء (Object initializer) نام دارد که از دو آکولاد باز و باز بسته استفاده می نماید و در داخل آنها خاصیت های مربوط به ساختار را مقدار دهی می کند.ملاحظه می فرمائید که خاصیت های بصورت لیستی از زوج های نام-مقدار تعریف شده اند که توسط کاما از یکدیگر جدا گشته اند.
سربار سازی سازنده یک ساختار (constructor overloading):
در دو مثال قبل، ایجاد یک ساختار را به دو روش مشاهده کردیم که در هر دو روش از سازنده (Constructor) پیش فرض ساختار ها استفاده شده است.این سازنده پیش فرض بصورت ضمنی در C# تعریف شده است و شما نمی توانید آن را خودتان پیاده سازی کنید.این سازنده تمامی فیلد های ساختار را با مقادیر پیش فرض مقدار دهی می کند.به این صورت که مثلا اعداد صحیح ۰، اعداد اعشاری ۰٫۰ و مقادیر بولی برابر با false مقدار می گیرند.چنانچه شما تابعی سازنده خاصی را نیاز داشته باشید می توانید یک سازنده جدید را به ساختار خود اضافه کنید که ممکن است پاراکتر هایی را هم بپذیرد.در مثال زیر چگونگی انجام این کار را با هم خواهیم دید.
struct Rectangle { private int m_width; public int Width { get { return m_width; } set { m_width = value; } } private int m_height; public int Height { get { return m_height; } set { m_height = value; } } // constructor overload public Rectangle(int width, int height) { m_width = width; m_height = height; } }
آخرین خط این ساختار یک سربار سازنده (constructor overload)است.نام سازنده ها دقیقا همان نام ساختار هایشان می باشند که در این مثال Rectangle است.همانطور که ملاحظه می کنید سربار سازنده ساختار Rectangle دو پارامتر را می پذیرد که به خاصیت های کپسوله شده ساختار نسبت داده می شوند.حال ببینیم که چگونه می توان از این سازنده برای ایجاد نمونه جدیدی از ساختار Rectangle استفاده نمود.
using System;
class StructExample
{
static void Main()
{
// ساختاری با عرض ۵ و ارتفاع ۷ را ایجاد می کند
Rectangle rect2 = new Rectangle(5, 7);
Console.WriteLine(“rect2: {0}:{1}”, rect2.Width, rect2.Height);
Console.ReadKey();
}
}
مثال بالا نمونه جدیدی از ساختار Rectangle را برای ما ایجاد می کند با این تفاوت که این بار بجای استفاده از سازنده پیش فرض از سربار سازنده استفاده می کند.در هنگام ایجاد ساختار rect2 ، دو مقدار ۵ و ۷ به سازنده پاس داده می شود.با نگاهی به تعریف سازنده مشاهده می کنید که عرض ساختار Rectanlge ما برابر با ۵ و طول آن برابر با ۷ خواهد شد.خروجی حاصل از اجرا تکه کد بالا بصورت زیر خواهد بود:
rect2: 5:7
افزودن یک متد به یک ساختار:
تا اینجا دیدیم که چگونه می توان به یک ساختار خاصیت هایی افزود و همچنین برای آن سازنده جدیدی تعریف نمود.حال می خواهیم ببنیم که چطور می شود متد جدیدی را نیز برای آن تعریف نمود.تعریف متد در یک ساختار نیز کاملا مشابه با کلاس ها می باشد.در مثال زیر نحوه افزودن متد add را به ساختار Rectangle می بنید.
struct Rectangle
{
private int m_width;
public int Width
{
get
{
return m_width;
}
set
{
m_width = value;
}
}
private int m_height;
public int Height
{
get
{
return m_height;
}
set
{
m_height = value;
}
}
public Rectangle(int width, int height)
{
m_width = width;
m_height = height;
}
public Rectangle Add(Rectangle rect)
{
Rectangle newRect = new Rectangle();
newRect.Width = Width + rect.Width; newRect.Height = Height + rect.Height;
return newRect;
}
}
در این مثال متد add عرض و ارتفاع مستطیل فعلی را با عرض و ارتفاع مستطیلی که بعنوان پارامتر به آن ارسال می شود جمع کرده و مستطیل جدیدی را با عرض و ارتفاع جدید بعنوان خروجی باز می گرداند.
فراخوانی متد یک ساختار :
حال می خواهیم با هم ببینیم که چگونه می توان متد های یک ساختار را از خارج آن فراخوانی نمود.برای اینکار ابتدا باید نمونه ای از ساختار را ایجاد نموده و سپس مانند مثال زیر فراخوانی متد مورد نظر را انجام دهیم.
using System;
class StructExample
{
static void Main()
{
Rectangle rect1 = new Rectangle();
rect1.Width = 1;
rect1.Height = 3;
Console.WriteLine(“rect1: {0}:{1}”, rect1.Width, rect1.Height);
Rectangle rect2 = new Rectangle(5, 7);
Console.WriteLine(“rect2: {0}:{1}”, rect2.Width, rect2.Height);
// فراخوانی متد add()
Rectangle rect3 = rect1.Add(rect2);
Console.WriteLine(“rect3: {0}:{1}”, rect3.Width, rect3.Height);
Console.ReadKey();
}
}
همانطور که در مثال بالا مشاهده می کنید، در متد main() دو ساختار با نام های struct1 و struct2 ایجاد می شودکه هر دو از نوع ساختار Rectangle می باشند.پس از آن خاصیت های عرض و ارتفاع آنها مقدار دهی می گردد.فکر می کند دیگر روش های ایجاد ساختار ها در مثال بالا برای شما آشنا باشند چراکه در مثال های قبلی هر دو روش توضیح داده شد.موردی که می خواهم توجه شم را به آن جلب کنم روش فراخوانی متد add می باشد.در این فراخوانی متد add از ساختار Rect1 صدا زده می شود و rect2 بعنوان پارامتر به آن ارسال می گردد.آنچه بعنوان خروجی این فراخوانی باز گردانده می شود یک ساختار بزرگتر است که عرض و ارتفاع آن برابر با حاصل جمع عرض و ارتفاع rect1 و rect2 می باشد.این ساختار بزرگتر به Rect3 نسبت داده می شود.خروجی حاصل از اجرای کد بالا بضورت زیر خواهد بود:
rect1: 1:3
rect2: 5:7
rect3: 6:10
بعنوان جمع بندی می توان گفت که در این مقاله آموزشی ما ساختار ها را تعریف کردیم و به تفاوت های اصلی آن با کلاس ها نیز اشاره نمودیم.همچنین شما با چگونگی ساخت یک ساختار، تعریف خاصیت ها و متد ها برای آن و نحوه استفاده از آنها را فرا گرفتید.امیدوارم این مقاله آموزشی برای شما مفید فایده واقع شده باشد.
موفق و پیروز باشید.
منبع : csharp-station
آخرین دیدگاهها