С# для AS3 разработчиков. Часть 3: get, set, sealed, using, const, readonly

в 8:01, , рубрики: as3, flash, Flash-платформа, unity

image

Перевод статьи From AS3 to C#, Part 3: AS3 Class Parity

Сегодня мы закончим разбираться с классами в C# (с точки зрения AS3 разработчика) и подготовимся к следующей статье, в которой мы сможем познакомиться с понятиями, аналогов которых нет в AS3. В текущей статье мы рассмотрим способ реализации:
— геттеров/сеттеров (getter/setter)
— функций и классов, которые нельзя переопределять/наследовать (final)
— констант
— пакетов

Get/Set функции

Давайте начнём с геттеров и сеттеров. Чтобы освежить память, вот, как они выглядели в AS3:

class Person
{
    private var _name:String;
    public function get name(): String
    {
        return _name;
    }
    public function set name(n:String): void
    {
        _name = n;
    }
}

А вот, эквивалент в С#:

class Person
{
    private String _name;
    public String Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
        }
    }
}

Как мы можем увидеть, в C#, вместо объявления 2 функций, геттер и сеттер объявлены в виде единственной переменной. Правда, эта переменная не заканчивается точкой с запятой (;), а содержит блок в виде фигурных скобок, внутри которого есть 2 части: get{} и set{}. Эти части являются геттер и сеттер функциями. Внутри сеттера у вас будет доступ к новому ключевому слову value, оно представляет собой значение, которое должно быть установлено и вам не нужно объявлять его, как это приходилось делать в AS3. Если не брать в расчёт это отличие в синтаксисе, геттеры и сеттеры работают одинаково в C# и AS3.

C# предоставляет возможность использовать сокращённую запись для подобных функций, позволяя избежать написание лишнего кода для простых функций:

class Person
{
    public String Name { get; set; }
}

Использование этой конструкции автоматически создаст переменную _name и геттер/сеттер функции, как в примере выше. Но что, если вам не нужна функция-сеттер? Просто уберите её:

class Person
{
    public String Name { get; }
}

Скорее всего, вам необходимо будет, как минимум, предоставить возможность классу Person устанавливать значения этой переменной. Для этого сеттер может быть объявлен private:

class Person
{
    public String Name { get; private set; }
}

И ещё, немного терминологии C#: поля класса, у которых есть get и/или set функции (Name), называются “свойства”. Переменные, которые используются для хранения этих данных (_name), называются “вспомогательные поля”.

Final/sealed функции

А теперь, давайте поговорим о final функциях, которые не могут быть переопределены (AS3):

class Person
{
    final function print(): void
    {
        trace("I'm a Person");
    }
}
class MyPerson extends Person
{
    // illegal
    override function print(): void
    {
        trace("I'm not just a Person, I'm a MyPerson too");
    }
}

С# предоставляет идентичный функционал, используя слово sealed:

class Person
{
    sealed void Print()
    {
        Debug.Log("I'm a Person");
    }
}
class MyPerson extends Person
{
    // illegal
    override void Print()
    {
        Debug.Log("I'm not just a Person, I'm a MyPerson too");
    }
}

Пакеты и namespace

Пакеты в AS3:

package com.jacksondunstan.examples
{
    class Person
    {
    }
}

В C#, пакеты называются namespace, вот и всё:

namespace com.jacksondunstan.examples
{
    class Person
    {
    }
}

Чтобы получить доступ к пакету внутри .as файла, вы можете импортировать пакет:

import com.jacksondunstan.examples;
class Printer
{
    function print(person:Person): void
    {
        trace("person has name: " + person.name);
    }
}

В C# вы используете ключевое слово using для namespace:

using com.jacksondunstan.examples;
class Printer
{
    void Print(Person person)
    {
        Debug.Log("person has name: " + person.name);
    }
}

Константы и readonly переменные

И напоследок, давайте поговорим о константах. Вот, как в AS3 может быть создано поле, которое нельзя изменить после объявления:

class Person
{
    private static const MIN_TEEN_AGE:int = 13;
    private static const MAX_TEEN_AGE:int = 19;
    var age:int;
    function IsTeen(): Boolean
    {
        return age >= MIN_TEEN_AGE && age <= MAX_TEEN_AGE;
    }
}

Вот, как это можно сделать в C#:

class Person
{
    private const int MinTeenAge = 13;
    private const int MaxTeenAge = 19;
    int Age;
    bool IsTeen()
    {
        return Age >= MinTeenAge && Age <= MaxTeenAge;
    }
}

Важный нюанс: в C# для констант можно использовать только базовые типы (например, int) и строки. Это необходимо потому, что подобное поле не будет существовать на самом деле, вместо этого, везде, где оно используется, будут подставлены значения этого поля. Так же, это означает, что подобные поля автоматически становятся статическими (static), и их не нужно объявлять, как static отдельно. После компиляции класс Person в C# будет выглядеть следующим образом:

class Person
{
    int Age;
    bool IsTeen()
    {
        return Age >= 13 && Age <= 19;
    }
}

В AS3 ключевое слово const использовалось исключительно для проверки на этапе компиляции и не приводило к изменениям/подстановкам в коде. Если необходимо добиться похожего поведения в C# или необходимо использовать не базовый тип данных (например, Person), то нужно использовать ключевое слово readonly:

class Person
{
    static readonly Person Newborn = new Person(0);
    readonly int Age;
    Person(int age)
    {
        Age = age;
    }
}

В примере выше присутствует 2 readonly поля:

1) Newborn – поле, которое было объявлено с ключевым словом static (readonly поля, в отличии от констант, не обязательно являются static). Данное поле будет инициализировано в том месте, где оно объявлено (по-аналогии с константами в AS3).

2) Age – поле, которое является readonly, но не является static. Оно будет инициализировано в конструкторе.

В завершении, сравнение описанных особенностей C# и AS3 кода:

////////
// C# //
////////
 
// Collection of classes being used by this file
using org.apache.coolstuff;
 
// Collection of classes
namespace com.jacksondunstan.examples
{
    class Person
    {
        // Complex getters and setters
        private String _name;
        String Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
 
        // Simple getters and setters
        int Age { get; set; }
 
        // Read-only field
        readonly int ID;
 
        // Inlined field
        const int AdultAge = 18;
 
        // Function that can't be overridden
        sealed void Print()
        {
            Debug.Log("Name: " + name + ", ID: " + ID);
        }
    }
}

/////////
// AS3 //
/////////
 
// Collection of classes being used by this file
import org.apache.coolstuff;
 
// Collection of classes
package com.jacksondunstan.examples
{
    class Person
    {
        // Complex getters and setters
        private var _name:String;
        function get name(): String
        {
            return _name;
        }
        function set name(value:String): void
        {
            _name = value;
        }
 
 
 
 
        // Simple getters and setters
        // {not supported. use complex instead.}
 
        // Read-only field
        const var ID:int;
 
        // Inlined field
        // {not supported. use compile-time constants via command-line instead.}
 
        // Function that can't be overridden
        final function print(): void
        {
            trace("Name: " + name + ", ID: " + ID);
        }
    }
}

В следующей статье мы, наконец-то, начнём рассматривать понятия, аналогов которых нет в AS3.

Не переключайте канал!

Автор: COOL_ALMANAH

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js