代码之家  ›  专栏  ›  技术社区  ›  Eric Belair

是否可以要求函数参数是函数类的静态常量?

  •  0
  • Eric Belair  · 技术社区  · 16 年前

    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 回复  |  直到 16 年前
        1
  •  1
  •   mweiss    16 年前

    为了扩展Dan R的答案,您可以创建一个严格的事件(如枚举的方式)类,如下所示:

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

        2
  •  1
  •   Christian Nunciato    16 年前

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

    所以答案是否定的——不管怎样,如果你在扩展事件的话就不是了。因为初始参数必须是一个字符串(在扩展事件的范围内),所以不管您使用多少级别的间接寻址,您最终仍将根据有效值列表检查参数。传入字符串以外的任何内容都将引发运行时错误。

        3
  •  1
  •   Joeflash    16 年前

    克里斯蒂安是对的——这个问题包含了一个模棱两可的术语。当您检查事件“类型”时,它们不是数据类型,即类对象,它们只是将事件的特定“味道”传递给侦听对象的字符串值。

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

    obj.addEventListener(CustomEvent.TYPE_WHICH_DOES_NOT_EXIST, handlerMethod);
    

        4
  •  0
  •   cwallenpoole    16 年前

    如果要将每个静态常量都设为大写常量名称的小写字符串,则可以执行以下操作:

    if( class.hasOwnProperty( type.toUpperCase() ) )
    {
        // Do something
    }
    else
    {
        // Failure
    }
    
        5
  •  0
  •   Dan R    16 年前

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

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