Софтуерно Инженерство
Loading...
+ Нов въпрос
ArmenPotourlyan+deleted! avatar ArmenPotourlyan+deleted! 488 Точки

[Useful Info] C# Properties

Здравейте, колеги,

 

Реших да пусна една тема за свойствата в C# като опит да осмисля това, което знам за тях. Надявам се, че информацията ще е полезна за тези, които не се чувстват комфортно с тях. Ще се радвам, ако се включите в дискусията.

 

Как стигаме до свойства?

Нека имаме един клас Person и в него едно публично (public) поле age, което да пази информацията за възрастта.  

public class Person
{
    public int age;
}
// В Main метода
var armen = new Person() { age = 26 };
Console.WriteLine(armen.age); // 26

Нека си представим, че сме маниаци на тема контрол, така че не искаме да има директен достъп до полето. Правим го частно (private) и така вече то не се вижда извън класа. За да го променяме и взимаме, дефинираме два метода GetAge и SetAge(int value).

private int age;

public int GetAge()
{
    return this.age;
}

public void SetAge(int value)
{
    this.age = value;
}
// В Main метода
var armen = new Person();
armen.SetAge(26);
Console.WriteLine(armen.GetAge()); // 26

Отлично, но в C# има вече вградена тази функционалност във вида на свойства (properties). Защо не се възползваме:

private int age;

public int Age
{
    get { return this.age; }
    set { this.age = value; }
}
// В Main метода
var armen = new Person() { Age = 26 };
Console.WriteLine(armen.Age); // 26

Тук value характеризира стойността, която получаваме при “сетването” (напр. armen.Age = 26, т.е. value е 26).

 

Супер, но C# позволява още по-съкратен запис (известно още като автоматични свойства – automatic properties):

public int Age { get; set; }

В този вариант елиминирахме полето и ако се чудите къде тогава поставяме стойности и откъде ги взимаме – компилаторът автоматично генерира поле, което да служи за тази цел (подозирам, че оттук идва наименованието automatic properties).

 

Един момент... Имахме едно публично поле и изведнъж се появи някакво свойство. Защо ни трябват свойства изобщо?!

Ето пример, при който свойството ни върши чудесна работа:

private int age;

public int Age
{
    get { return this.age; }
    set
    {
        if (value < 0)
            throw new ArgumentException();
        this.age = value;
    }
}

Тук правим валидация на стойността – възрастта не може да е отрицателна. Надявам се сте съгласни, че ако имахме едно единствено публично поле – нямаше да успеем да го направим това вътре в класа.

 

Изведнъж ни скимва, че ще променим начина, по който пазим възрастта – ще добавим поле, което да пази рождената дата на въпросния човек и конструктор, в който я поставяме. Възрастта ще пресмятаме спрямо датата в момента.

private DateTime birthday;

public Person(DateTime birthday)
{
    this.birthday = birthday;
}

public int Age
{
    get
    {
        var birthDayAndMonth =
            new DateTime(DateTime.Today.Year, birthday.Month, birthday.Day);
        var age = (DateTime.Today >= birthDayAndMonth)
            ? DateTime.Today.Year - birthday.Year
            : DateTime.Today.Year - birthday.Year - 1;
        return age;
    }
}
// В Main метода
var armen = new Person(new DateTime(1989, 12, 10));
Console.WriteLine(armen.Age); // 26

Променихме вътрешното представяне на възрастта, но отвън достъпът ни до Age свойството е пак същото. Примерът не е съвсем подходящ, понеже добавихме конструктор и премахнахме “сетъра”, но загатва, че може да изменяме вътрешно класа –  вида на структурите, които ползваме за съхранение на данните, а в същия момент обектите отвън да се ползват по стария начин сякаш няма никакви изменения (тук се докосваме до енкапсулацията като принцип в ООП). Един вид свойствата представляват интерфейс (да не се бърка с интерфейс от ООП) – начин да взаимодействаме с обект на класа.

 

Друга причина да ползваме свойства, за която се сещам, е да улесним живота на този, който ще ползва класа – вместо десетки свойства (които със сигурност ще присъстват, ако си представим, че Person моделира реален човек), ние му даваме да пипа няколко свойства без да се притеснява за това какво се крие зад тях (тук се докосваме до абстракцията като принцип в ООП).

 

И трите неща – валидация на данните, изменение на вътрешната структура на данните и дефиниране на начин за взаимодействие с външния свят, могат да се постигнат с двойки Get и Set методи (в Javа, ако не се лъжа, се прави така). Методите обикновено характеризират поведение (behavior), а поставянето и взимането на стойности със сигурност не демонстрира поведение на даден обект. При свойствата няма такъв проблем и са много по-удобни за работа (представете си купищата Set/GetНещоСи методи, които трябва да извикате иначе).

 

DISCLAIMER: Последните дни не съм спал много, ще ме прощавате, ако съм изръсил някоя глупост :)))

Тагове:
15
C# OOP Basics
aruseva avatar aruseva 29 Точки

Браво! Страхотно си го обяснил! 

0
22/06/2016 14:05:04
Alex0101 avatar Alex0101 375 Точки

Супер е! Много полезно и много достъпно обяснено. 

Продължавай все така, колега!

0
RoYaL avatar RoYaL SoftUni Team Trainer 6846 Точки

Поздравления за детайлното обяснение! :)

1