你能否要求函数参数是函数类的静态常量?

时间:2009-05-22 18:42:02

标签: flex actionscript-3 events static constants

假设我有一个自定义事件类,它有几个以静态常量存储的事件类型:

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 个答案:

答案 0 :(得分:1)

为了延伸Dan R的答案,你可以创建一个严格的事件(就像你做enums的方式)这样的课程:

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);
        }
    }


  }

然后,您可以通过扩展strict事件类并在静态初始化程序中调用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);
    }

}

现在,每次创建一个事件时,它只需要查找事件对象并查看该类型是否在该对象中。这也意味着您不必手动添加初始化程序中的所有常量。

答案 1 :(得分:1)

虽然这两个答案都提供了验证字符串值的不同解决方案,但它们没有回答有关来检查值的问题。你必须做的,至少因为常量的值是字符串本身。

所以答案是否定的 - 不管你是否正在扩展事件。由于该初始参数必须是String(在您扩展Event的范围内),无论您使用多少级别的间接,您仍将最终根据有效值列表检查参数。传入除String之外的任何内容都会引发运行时错误。

答案 2 :(得分:1)

克里斯蒂安是正确的 - 这个问题含有一个含糊不清的术语。当您检查事件“类型”时,它们不是数据类型,即类对象,它们只是将事件的特定“风格”传递给侦听对象的字符串值。

就个人而言,我认为您不需要对事件类型进行运行时验证。如果您的代码尝试使用不存在的事件常量,例如

obj.addEventListener(CustomEvent.TYPE_WHICH_DOES_NOT_EXIST, handlerMethod);

...在代码运行之前,您将遇到编译器错误。如果对事件类型使用原始字符串值,那么无论如何都要破坏使用事件常量的目的。

答案 3 :(得分:0)

如果你要将每个静态常量作为大写常量名称的小写字符串,那么你可以这样做:

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

答案 4 :(得分:0)

有几种方法可以解决这个问题:

  1. 对类型使用枚举方法以保证它在列表中。构造函数中的参数将不再是字符串,而是枚举。有关在AS3中复制枚举的方法,请参阅http://blog.petermolgaard.com/2008/11/02/actionscript-3-enums/
  2. 在类中使用静态构造函数将类型列表填充到ArrayCollection中,并使用.contains()方法检查成员资格。 (可能在下面实施)
  3. 您的代码示例似乎是一个事件类。如果是这种情况,则不能使用第一个选项,因为如果您不需要,则不希望更改构造函数的签名。

    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");
            }
        }
    }