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
RoYaL avatar RoYaL Trainer 6849 Точки

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

1
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.