Можете ли вы потребовать, чтобы параметр функции был статической константой класса функции? - PullRequest
0 голосов
/ 22 мая 2009

Допустим, у меня есть пользовательский класс событий, и он имеет несколько типов событий, хранящихся в статической константе:

package customEvents
{
    public class 
    {
        public static const DISAPPEAR_COMPLETELY:String = "disappearCompletely";

        public static const SIT_DOWN:String = "sitDown";

        public static const STAND_UP:String = "standUp";

        public static const SAIL_TO_THE_MOON:String = "sailToTheMoon";

        public static const GO_TO_SLEEP:String = "goToSleep";

        public static const GO_SLOWLY:String = "goSlowly";

        public function MyCustomEvent(type:String)
        {
            super(type);
        }
    }
}

Есть ли простой способ проверить, что type, переданный Конструктору, является одной из статических констант класса, не проверяя ее по каждому значению?

Ответы [ 5 ]

1 голос
/ 23 мая 2009

Кристиан прав - и вопрос содержит несколько двусмысленный термин. Когда вы проверяете «типы» событий, они не являются типами данных, то есть объектами классов, они просто являются строковыми значениями, которые передают определенный «аромат» события прослушивающему объекту.

Лично я не думаю, что вам нужна проверка типов событий во время выполнения. Если ваш код пытается использовать несуществующую константу события, например

obj.addEventListener(CustomEvent.TYPE_WHICH_DOES_NOT_EXIST, handlerMethod);

... вы получите ошибку компилятора еще до запуска вашего кода. Если вы используете необработанные строковые значения для типов событий, то вы все равно побеждаете цель использования констант событий.

1 голос
/ 23 мая 2009

Хотя оба эти ответа предлагают разные решения для проверки строковых значений, они не отвечают на вопрос о , имеющем для проверки значений. Что вы должны сделать, по крайней мере, потому что значения констант - это сами строки.

Так что ответ - нет, во всяком случае, если вы расширяете Event. Поскольку этот начальный параметр должен быть строкой (поскольку вы расширяете Event), независимо от того, сколько уровней косвенности вы используете, вы все равно будете проверять аргументы по списку допустимых значений. Передача чего-либо кроме String вызовет ошибку времени выполнения.

1 голос
/ 22 мая 2009

Чтобы расширить ответ Дана Р., вы можете создать строгий класс событий (как, например, перечисления):

import flash.utils.Dictionary;
import flash.utils.describeType;
import flash.utils.getQualifiedClassName;

public class StrictEvent
{   
    private static var VALID_EVENTS:Dictionary = new Dictionary();

    public static function initEvents(inType:*):void {
        var events:Object = {};
        var description:XML = describeType(inType);
        var constants:XMLList = description.constant;
        for each(var constant:XML in constants) {
          events[inType[constant.@name]] = true;
        }
        VALID_EVENTS[getQualifiedClassName(inType)] = events;
    }

    public function StrictEvent(type:String)
    {
        var className:String = getQualifiedClassName(this);
        if(VALID_EVENTS[className][type]) {
            // init
        } else {
            throw new Error("Error! " + type);
        }
    }


  }

Затем вы можете определить свой собственный класс событий, расширив класс строгих событий и вызвав initEvents в статическом инициализаторе. Вот ваш пример с этим методом:

public class CustomEvent extends StrictEvent
{

    public static const DISAPPEAR_COMPLETELY:String = "disappearCompletely";

    public static const SIT_DOWN:String = "sitDown";

    public static const STAND_UP:String = "standUp";

    public static const SAIL_TO_THE_MOON:String = "sailToTheMoon";

    public static const GO_TO_SLEEP:String = "goToSleep";

    public static const GO_SLOWLY:String = "goSlowly";

    public function CustomEvent(type:String) {
        super(type);
    }    

    {
      initEvents(CustomEvent);
    }

}

Теперь, каждый раз, когда он создает событие, ему нужно только найти объект события и посмотреть, относится ли тип к этому объекту. Это также означает, что вам не нужно вручную добавлять все константы в инициализаторе.

0 голосов
/ 22 мая 2009

Есть несколько способов атаковать это:

  1. Используйте подход enum для типов, чтобы гарантировать, что он находится в списке. Параметр в конструкторе будет больше не строкой, а перечислением. См. http://blog.petermolgaard.com/2008/11/02/actionscript-3-enums/ способ репликации перечислений в AS3.
  2. Используйте статический конструктор в вашем классе, чтобы заполнить список типов в ArrayCollection, и используйте метод .contains () для проверки членства. (Возможная реализация ниже)

Ваш пример кода, похоже, класс событий. Если это так, вы не можете использовать первый вариант, так как вы не захотите менять подпись конструктора, если вам это не нужно.

package customEvents
{
    public class 
    {
        private static var typeList:ArrayCollection;

        public static const DISAPPEAR_COMPLETELY:String = "disappearCompletely";
        public static const SIT_DOWN:String = "sitDown";
        <... lines deleted ...>
        public static const GO_SLOWLY:String = "goSlowly";

        // static constructor    
        {
            typeList = new ArrayCollection();

            typeList.addItem(DISAPPEAR_COMPLETELY);
            typeList.addItem(SIT_DOWN);
            <... lines deleted ...>
            typeList.addItem(GO_SLOWLY);

        public function MyCustomEvent(type:String)
        {
            if (typeList.contains(type)
                super(type);
            else
                throw new Error("Invalid type");
        }
    }
}
0 голосов
/ 22 мая 2009

Если бы вы должны были сделать каждую из статических констант как строчными буквами имен констант верхнего регистра, то вы могли бы сделать:

if( class.hasOwnProperty( type.toUpperCase() ) )
{
    // Do something
}
else
{
    // Failure
}
...