2009-05-22 58 views
0

比方說,我有一個自定義事件類,它具有存儲在靜態常量幾個事件類型:你能否要求函數參數是函數類的靜態常量?

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是靜態常量之一該類,而不必檢查它對每個值?

回答

0

如果你使每個靜態常量爲大寫的常量名的小寫字符串,那麼你可以做:

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

有可以攻擊這幾種方法:

  1. 對類型使用enum方法來保證它在列表中。構造函數中的參數不再是一個字符串,而是一個枚舉。有關在AS3中複製枚舉的方法,請參見http://blog.petermolgaard.com/2008/11/02/actionscript-3-enums/
  2. 在您的類中使用靜態構造函數將類型列表填充到ArrayCollection中,並使用.contains()方法檢查成員資格。 (可能的實現如下)

你的代碼示例似乎是一個事件類。如果是這樣的話,你不能使用第一個選項,因爲如果你不需要,你不想改變構造函數的簽名。然後

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[[email protected]]] = 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); 
     } 
    } 


    } 

,你可以定義你的自定義事件:

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

爲了擴大關丹的r答案,你可以像這樣建立了嚴格的事件(如你會做枚舉的方式)類類通過擴展嚴格事件類並在靜態初始化器中調用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

雖然這兩個答案都提供了不同的解決方案來驗證字符串值,但他們不回答來檢查值的問題。你必須這樣做,至少因爲常量的值是Strings本身。

所以答案是否定的 - 不是如果你擴展事件,無論如何。由於初始參數必須是字符串(就擴展事件而言),無論您使用多少級別的間接引用,您最終仍然會根據有效值列表來檢查參數。傳入除String之外的任何內容都會引發運行時錯誤。

+0

我想他是問你是否必須檢查每一個O(N),而不是檢查散列O(1)。 – mweiss 2009-05-22 21:44:56

1

基督徒是正確的 - 問題包含了一個有點含糊的詞彙。在檢查事件「類型」時,它們不是數據類型,即類對象,它們只是將事件的特定「味道」傳遞給聆聽對象的字符串值。

就我個人而言,我不認爲你需要事件類型的運行時驗證。如果你的代碼試圖使用一個事件常數,它不存在,如

obj.addEventListener(CustomEvent.TYPE_WHICH_DOES_NOT_EXIST, handlerMethod); 

...你會得到一個編譯錯誤你的代碼甚至可以運行了。如果您使用原始字符串值作爲事件類型,那麼您無論如何擊敗了使用事件常量的目的。

+0

爲了扮演魔鬼的擁護者,如果將CustomEvent.TYPE_WHICH_DOES_NOT_EXIST改爲用一種不那麼簡單的方式確定的變量呢? – mweiss 2009-05-22 22:59:15