در توسینسو تدریس کنید

و

با دانش خود درآمد کسب کنید

آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 4 : Property ها

در قسمت قبلی آموزش، در مورد فیلدها و نحوه تعریف آنها در کلاس آشنا شدیم، اما گاهی اوقات نیاز داریم که بر روند مقداردهی و گرفتن مقدار یک فیلد نظارت داشته باشیم. زمانی که یک فیلد تعریف می کنیم، عملیات انتساب مقدار و گرفتن مقدار به صورت مستقیم از داخل فیلد انجام شده و امکان انجام هیچ گونه نظارتی بر روی این عملیات ها وجود ندارد. برای رفع این مشکل، دو راه وجود دارد:

  1. استفاده از متدها برای ست کردن و گرفتن مقدار از فیلد.
  2. استفاده از Property ها

افرادی که با زبان جاوا آشنا هستند با متدهای get و set در کلاس ها آشنایی دارند. این متدها عملیات خواندن و نوشتن در فیلدها را برای ما انجام می دهند. مثالی از زبان سی شارپ می زنیم. کلاس Person را در نظر بگیرید:

public class Person
{
    public string FirstName;
    public string LastName;
}

این کلاس، ما زمانی که یک شئ از این کلاس می سازیم به صورت مستقیم فیلدها را مقدار دهی کرده یا مقدار آنها را می خوانیم. اما برای کنترل دسترسی به فیلدها، ابتدا باید سطح دسترسی فیلدها را به private تغییر بدیم. زمانی که یک عضو کلاس که در اینجا فیلدها هستند را به private تغییر می دهیم، آن عضو تنها داخل همان کلاس قابل دسترس خواهد بود. برای اولین قدم، کلاس Person را به صورت زیر تغییر می دهیم:

public class Person
{
    private string firstName;
    private string lastName;
}

به نام گذاری فیلدها دقت کنید، زمانی که فیلدها به private تغییر کردند، نام گذاری بر اساس قاعده camelCase انجام می شود. این قاعده برای کلیه فیلدهای private کلاس ها حکم می کند. البته الزامی به این کار نیست، اما برای رعایت اصول کد نویسی بهتر است از این قواعد پیروی کنیم. بعضی از برنامه نویس ها ابتدای نام فیلدهای private از کاراکتر __ استفاده می کنند. این موضوع کاملاً دلخواه می باشد، اما سعی کنید در نام گذاری فیلدها public و private تفاوت قایل شوید.در قدم بعدی باید بتوانیم در خارج از کلاس، عملیات خواندن و مقدار دهی فیلد را انجام دهیم. در روش اول گفتیم که از متدهای get و set برای اینکار استفاده می کنیم. کلاس Person را به صورت زیر تغییر می دهیم:

public class Person
{
    private string firstName;
    private string lastName;

    public string GetFirstName()
    {
        return firstName;            
    }

    public void SetFirstName(string value)
    {
        firstName = value;
    }

    public string GetLastName()
    {
        return lastName;
    }

    public void SetLastName(string value)
    {
        lastName = value;
    }
}

در تصویر زیر، لیست نمایش داده شده برای شئ ای از کلاس Person را مشاهده می کنید:

i1

حال می توانیم عملیات خواندن و نوشتن فیلدها را در خارج از کلاس بوسیله این دو متد انجام دهیم:

var person = new Person();

person.SetFirstName("Hossein");
person.SetLastName("Ahmadi");

Console.WriteLine(person.GetFirstName() + " " + person.GetLastName());
Console.ReadLine();

حال فرض کنید، یک فیلد باید تنها خواندنی باشد، برای اینکار کافیست بخش Set را از کلاس حذف کنید یا فرض کنید عملیات نوشتن باید تنها در داخل خود کلاس انجام شود و از بیرون کلاس دسترسی نوشتن باید بسته شود، برای این کار کافیست که دسترسی متد Set برای فیلد مورد نظر را به private تغییر دهیم. در مثال زیر عملیات نوشتن برای فیلد firstName به صورت private تعریف شده و فیلد lastName قابلیت نوشتن ندارد:

public class Person
{
    private string firstName;
    private string lastName;

    public string GetFirstName()
    {
        return firstName;            
    }

    private void SetFirstName(string value)
    {
        firstName = value;
    }

    public string GetLastName()
    {
        return lastName;
    }
}

استفاده از Property ها

اما در زبان سی شارپ به صورت دیگری می توان این کنترل را انجام داد و آن استفاده از Property ها می باشند. ساختار کلی property ها به صورت زیر می باشد:

{access-modifier} {data-type} {property-name}
{
    [access-modifier] get
    {
        // body for get value
    }
    [access-modifier] set
    {
        // body for set value
    }
}

اما بررسی هر یک از قسمت های ساختار Property:

  1. access-modifier: سطح دسترسی به Property را تعیین می کند. Property نیز مانند فیلد می تواند سطح دسترسی داشته باشد.
  2. data-type: نوع Property که یکی از Data Type های دات نت یا کلاسی که به صورت دستی نوشته شده باشد.
  3. property-name: نام Property، برای نام گذاری Property ها همیشه از قاعده PascalCase استفاده کنید، سطح دسترسی تفاوتی ندارد، همیشه PascalCase تعریف کنید.
  4. بدنه get: این بدنه، دقیقاً معادل متد Get ایست که در قسمت قبلی تعریف کردیم. شما داخل بدنه get هر دستوری را می توانید بنویسید، در حقیقت این بدنه مانند یک متد عمل کرده و زمانی که شما مقدار Property را می خوانید (مثلاً برای چاپ با دستور

WriteLine) بدنه get اجرا می شود. دقت کنید بدنه get حتماً باید مقداری را با دستور return بر گرداند. همچنین این بدنه می تواند دارای access-modifier باشد، یعنی سطح دسترسی خواندن مقدار را مشخص می کند. در صورتی که سطح دسترسی را

مشخص نکنید به صورت پیش فرض public در نظر گرفته می شود.

  1. بدنه set: این بدنه، دقیقاً معادل متد Set در مثال قبلی است. زمانی که شما مقداری را داخل Property ست می کنید، بدنه set اجرا می شود. داخل بدنه set پارامتر پیش فرضی وجود دارد به نام value که مقدار ست شده داخل Property داخل آن قرار

گرفته و شما می توانید به آن از داخل بدنه set دسترسی داشته باشید. همچنین می توان برای بدنه set سطح دسترسی را مشخص کرد. در صورتی که سطح دسترسی را مشخص نکنید به صورت پیش فرض public در نظر گرفته می شود.

به مثال کلاس Person بر می گردیم. تصمیم داریم عملیات هایی که در بوسیله متدهای Get و Set انجام دادیم را با Property ها پیاده سازی کنیم. کلاس Person را به صورت زیر تغییر دهید:

public class Person
{
    private string firstName;
    private string lastName;

    public string FirstName
    {
        get { return firstName; }
        set { firstName = value; }
    }

    public string LastName
    {
        get { return lastName; }
        set { lastName = value; }
    }
}

در کد بالا، دو Property با نام های FirstName و LastName تعریف کردیم که عملیات خواندن و نوشتن از فیلدهای مربوطه را انجام می دهند. نتیجه اعضای نمایش داده شده برای کلاس Person هنگام استفاده از نمونه یا Instance آن را در تصویر زیر مشاهده

می کنید:

i2

در ادامه کد متد Main را به صورت زیر تغییر دهید:

var person = new Person();

person.FirstName = "Hossein";
person.LastName = "Ahmadi";

Console.WriteLine(person.FirstName + " " + person.LastName);
Console.ReadKey();

در کد بالا، زمانی که مقدار Hossein را داخل فیلد FirstName ست می کنیم، بدنه set مربوط به خاصیت FirstName اجرا می شود که در این بدنه ما مقدار value که همان مقدار ست شده در هنگام استفاده از کلاس است را داخل فیلد firstName قرار می دهیم. برای LastName هم به همین صورت است. شاید بپرسید پارامتر value کجا تعریف شده است؟ این پارامتر به صورت پیش فرض برای بدنه set وجود دارد که نگه دارنده مقدار ست شده داخل Property است.

همچنین زمانی که داخل دستور WriteLine مقدار FirstName یا LastName را می خوانیم، بدنه get مربوط به همان Property اجرا می شود. در حقیقت Property ها واسطی میان فیلدها و استفاده کننده از کلاس ها هستند. مانند یک انبار دار که عملیات کنترل ورود و خروج از انبار را کنترل می کند و عملیات تحویل دادن کالا یا گرفتن کالا و قرار دادن آن در انبار را انجام می دهد.برای نوشتن Property ها، حتماً نیازی به تعریف Field برای آنها نیست، شما می توانید هر کدی را برای بدنه get یا set بنویسید. برای مثال، می خواهیم به کلاس Person یک Property تعریف کنیم که نام کامل شخص را بر گرداند. نام این خاصیت را FullName

می گذاریم:

public class Person
{
    private string firstName;
    private string lastName;

    public string FirstName
    {
        get { return firstName; }
        set { firstName = value; }
    }

    public string LastName
    {
        get { return lastName; }
        set { lastName = value; }
    }

    public string FullName
    {
        get { return FirstName + " " + LastName; }
    }
}

حال کد Main قسمت قبلی را می توان به صورت زیر تغییر داده و از Property جدیدی که تعریف کردیم استفاده کنیم:

var person = new Person();

person.FirstName = "Hossein";
person.LastName = "Ahmadi";

Console.WriteLine(person.FullName);
Console.ReadKey();

نگاهی دوباره به کلاس Person و خاصیت FullName می کنیم، اگر دقت کرده باشید این خاصیت تنها بدنه get را دارد و بدنه set را برای آن ننوشتیم. دلیل این امر آن است که FullName تنها برای ترکیبی از firstName و lastName را بر میگرداند. در صورتی که بخواهیم مقداری داخل FullName بریزیم، با پیغام خطا مواجه می شویم.

i3

Property هایی که بدنه get را ندارند Write-Only و آنهایی که بدنه set را ندارند Read-Only می گوییم. همچنین همانطور که قبلاً هم گفتیم می توانیم علاوه بر خود Property برای هر یک از بدنه های get و set نیز سطح دسترسی مشخص کنیم. برای مثال میخواهیم خاصیت FirstName تنها داخل خود کلاس قابلیت نوشتن داشته باشد، برای اینکار کافیست بدنه set را به صورت private تعریف کنیم:

public string FirstName
{
    get { return firstName; }
    private set { firstName = value; }
}

Automatic Properties

گاهی اوقات، Property که تعریف می کنیم تنها عملیات خواندن و نوشتن یک فیلد را کنترل می کند. برای مثال، کلاس Person را در نظر بگیرید:

public class Person
{
    private string firstName;

    public string FirstName
    {
        get { return firstName; }
        set { firstName = value; }
    }
}

کد مربوط به خصوصیت بالا را می توان به شکل زیر نیز نوشت:

public class Person
{
    public string FirstName { get; set; }
}

کامپایلر بعد از کامپایل کد بالا، به صورت خودکار یه فیلد برای خاصیت نوشته شده تعریف کرده و بدنه get و set آن را به صورت خودکار می نویسد. از مزیت های Auto-Property ها حجم کد کمتر و البته قابلیت کنترل دسترسی به عملیات های خواندن و نوشتن Property ها می باشد. مثال بالا را جوری تغییر می دهیم که خاصیت FirstName تنها داخل کلاس قابل نوشتن باشد:

public class Person
{
    public string FirstName { get; private set; }
}

به این نکته توجه داشته باشید، زمانی که از Auto-Property ها استفاده می کنید، حتماً باید get و set را بنویسید، در غیر اینصورت پیغام خطا دریافت خواهید کرد. البته این مشکل در نسخه 6 زبان سی شارپ برطرف شده است.در این قسمت با Property ها آشنا شدیم و متوجه شدیم که چگونه می توان عملیات خواندن و نوشتن مقادیر یک کلاس را کنترل کرد. در قسمت بعدی با مفهوم سازنده ها در کلاس ها آشنا شده و به بررسی حالت های مختلف ایجاد شئ از روی کلاس ها خواهیم پرداخت. ITPRO باشید

نویسنده : حسین احمدی

منبع : جزیره برنامه نویسی وب سایت توسینسو

هرگونه نشر و کپی برداری بدون ذکر منبع و نام نویسنده دارای اشکال اخلاقی است

#برنامه_نویسی_شی_گرا #آموزش_زبان_سی_شارپ #برنامه_نویسی_شئ_گرا #تعریف_property_در_زبان_سی_شارپ #آموزش_گام_به_گام_برنامه_نویسی_سی_شارپ #آموزش_برنامه_نویسی_شئ_گرا #خصوصیات_در_برنامه_نویسی_شئ_گرا #auto-property_در_زبان_سی_شارپ #آموزش_برنامه_نویسی_سی_شارپ #آموزش_برنامه_نویسی
عنوان
1 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 1 : مقدمه رایگان
2 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 2 : کلاس و شئ رایگان
3 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 3 : فیلد و متد رایگان
4 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 4 : Property ها رایگان
5 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 5: سازنده ها رایگان
6 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 6 : وراثت رایگان
7 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 7 : Polymorphism رایگان
8 آموزش برنامه نویسی شی گرا در (#C) قسمت 8 : abstract و sealed رایگان
9 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 9:سازنده در وراثت رایگان
10 برنامه نویسی شی گرا در سی شارپ (#C) قسمت 10: Exntesion Method ها رایگان
11 برنامه نویسی سی شارپ (#C) قسمت 11: Value Type و Reference Type رایگان
12 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 12 : Interface رایگان
13 آموزش برنامه نویسی شی گرا در (#C) قسمت 13: Dependency Injection رایگان
14 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 14 : تبدیل نوع رایگان
15 آموزش برنامه نویسی شی گرا (#C) قسمت 15 : Operator Overloading رایگان
16 برنامه نویسی شی گرا در سی شارپ (#C) قسمت 16 : Boxing و Unboxing رایگان
17 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 17 : Generics رایگان
18 آموزش برنامه نویسی شی گرا در (#C) قسمت 18 : List و Dictionary رایگان
19 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 19 : مدیریت خطاها رایگان
زمان و قیمت کل 0″ 0
7 نظر
+9****+77

سلام با عرض خسته نباشید

واقعا تشکر میکنم برای اموزش های رسانا و عالیتون که واقعا همچیزشو فهمیدم

ولی اینو ذکر کنم :

در قسمتی که گفتین اگر برای property ها سطح دسترسی مشخص نشه به صورت پیش فرض public در نظر گرفته میشه رو من امتحان کردم و برعکس اگر مشخص نشه به صورت پیش فرض مثل متغیر ها private در نظر گرفته میشه

لطفا چک کنید و اگر درست گفتم اصلاح کنیدش که بقیه به مشکل نخورن

بازم واقعا تشکر بابت اموزش عالیتون

حسین احمدی

سلام، وقت بخیر

اون قسمتی که شما فرمودید منظور قسمت get و set هست، نه خود property. برای خود property درسته، در صورت مشخص نکردن access modifier حالت private در نظر گرفته میشه، اما برای get و set پیش فرض public هست.

+9****+77

اره از اون نظر درسته
هرچی برای پروپرتی در نظر گرفته بشه میشه پیش فرض گت و ست
تشکر

+9****+77

سلام و با عرض خسته نباشید

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

الان وقتی ما خودمون تنظیم میکردیم برنامه میفهمید که منظورمون کدوم فیلد هست که کنترلش کنه یعنی دقیق در پروپرتی ما مشخص میکردیم در قسمت گت کدوم فیلد رو فرابخونه و در قسمت ست کدوم فیلد رو مقدار بده اما وقتی میام مثلا وقتی :

private string __carName;

public string CarName{get;set;}

برنامه چطور باید بفهمه که که منظور ما از این پروپرتی فیلد بالاس؟

کار اصلی پروپرتی که اصلا واسش ساخته شده کنترل فیلد هاست در صورتی که در این اتوماتیک ها واسه خودش یک متغیر کامله!

لطفا راهنماییم کنید

با تشکر از اموزش های خوبتون

+9****+77

در اصل ما اگه بخوایم از این اتوماتیک ها به عنوان یک متغیر کامل و بدون کنترل پابلیک استفاده کنیم خب از همون اول میایم یک متغیر معمولی پابلیک درست میکنیم که خیلی عقلانی تره!

حسین احمدی

سلام مجدد، چند تا نکته در مورد استفاده از Auto Property ها و دلیل استفادشون نسبت به فیلدهای public وجود داره که اینجا بهشون اشاره می کنم:

1. همونطور که میدونید Property ها یک قسمت Get دارن و یک قسمت Set و شما می تونید یک logic برای این قسمت ها در صورت نیاز اضافه کنید. ممکنه که بعدها نیاز باشه که یک Property داخل یک Assembly تغییر کنه و مثلاً برای بخش Set شما یک کد بنویسید که بررسی هایی روی این قسمت انجام بده. حالا اگه شما از Field استفاده کرده باشید و Assembly های دیگه ای از فیلد های شما استفاده کرده باشن و بخوایید فیلدها رو به Property تغییر بدید، نیاز هست که کلیه Assembly های وابسته مجدد Build و Publish بشن، اما اگر از Auto Property ها استفاده کرده باشید تنها باید Assembly مورد نظر به روز رسانی بشه.

2. یک جایی مثل Entity Framework رو در نظر بگیرید، شما برای Navigation ها که باید Lazy Load باشن یک Property به صورت زیر تعریف می کنید:

public virtual ICollection<Order> Orders { get; set; }

کار که کامپایلر انجام میده override کردن قسمت های get و set در کلاس Proxy هست که ایجاد میشه، شما اینجا نمی تونید Field تعریف کنید و اگر هم Auto Property ها نبودن این کد باید به صورت زیر تعریف می شد:

private ICollection<Order> _orders;

public virtual ICollection<Order> Orders
{
  get { return _orders; }
  set { _orders = value; }
}

این هم یک دلیل دیگه برای استفاده از Auto Property ها که کدتون رو به شدت ساده می کنه و دلیل اضافه شدنشون به زبان سی شارپ هست.

3. مورد بعدی Data Binding هست، خیلی جاها عملیات Data Binding با Field ها امکان پذیر نیست و شما باید حتماً از Property ها استفاده کنید که باز هم Auto Property ها کار شما رو راحت می کنن.

امیدوارم جواب سوالتون رو گرفته باشید.

+9****+77

سلام مجدد

حرف شما متین هستش درباره کلیت خوده property  های معمولی که اصلا برای کنترل بر روی فیلد ها ساخته شدن

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

حرف من در اصل برای automatic property  ها بود مثل

public string a1{get;set;}

که دیگه هیچ کنترلی بر روی فیلد ها نیست

منظور من اینه این نوع پروپرتی ها اصلا چه تفاوتی با فیلد دارن وقتی که نمیشه کنترلی بر روشون داشت

نه پروپرتی های معمولی

نظر شما
برای ارسال نظر باید وارد شوید.
از سرتاسر توسینسو
تنظیمات حریم خصوصی
تائید صرفنظر
×

تو می تونی بهترین نتیجه رو تضمینی با بهترین های ایران بدست بیاری ، پس مقایسه کن و بعد خرید کن : فقط توی جشنواره پاییزه می تونی امروز ارزونتر از فردا خرید کنی ....