2009-05-22 4 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의 대답 떨어져 확장하려면, 당신과 같이 클래스를 (당신이 열거 할 거라고 방법 등) 엄격한 이벤트를 만들 수 있습니다 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

이 두 가지 대답은 문자열 값의 유효성을 검사 할 때 다른 해결책을 제시하지만 에 대한 질문에이 있으면 값을 확인하지 않습니다. 상수의 값은 문자열 자체이기 때문에 최소한해야합니다.

그래서 답은 아니오입니다. 어쨌든 이벤트를 확장하는 경우가 아닙니다. 초기 매개 변수는 String이어야합니다 (이벤트를 확장하는 경우). 간접 사용의 수준에 관계없이 유효한 값 목록에 대해 인수를 확인하게됩니다. String이 아닌 다른 것을 전달하면 런타임 오류가 발생합니다.

+0

해시 O (1)을 검사하는 것과는 대조적으로 그가 각 O (N)을 검사해야하는지 여부를 묻는 것입니다. – mweiss

1

기독교인이 맞습니다. 질문에 다소 모호한 용어가 포함되어 있습니다. 이벤트 "유형"을 확인하는 경우 데이터 유형, 즉 클래스 객체가 아니며 단순히 이벤트의 특정 "풍미"를 따라 청취 객체로 전달되는 문자열 값입니다.

개인적으로 필자는 이벤트 유형의 런타임 유효성 검사가 필요하지 않다고 생각합니다.코드가 존재하지 않는 이벤트 상수 (예 :

obj.addEventListener(CustomEvent.TYPE_WHICH_DOES_NOT_EXIST, handlerMethod); 

...)를 사용하려고하면 코드가 실행되기 전에 컴파일러 오류가 발생합니다. 이벤트 유형에 원시 문자열 값을 사용하면 어쨌든 이벤트 상수를 사용하는 목적을 상실하게됩니다.

+0

악마의 옹호자를 재생하려면 CustomEvent.TYPE_WHICH_DOES_NOT_EXIST 대신 덜 간단한 방법으로 결정된 변수로 대체하면 어떻습니까? – mweiss

+0

@mweiss, 간단한 문자열 값과 마찬가지로? 최악의 경우는 이벤트가 전혀 들리지 않으므로 처리기가 실행되지 않습니다. –

+0

이벤트 유형 상수 대신에 변수를 사용할 수 있습니다.하지만 어딘가에서 리스너를 선언하기 전에 해당 변수에 값을 전달해야합니다. 해당 값이 존재하지 않는 유형 상수 인 경우 여전히 컴파일 오류가 발생합니다. 이 값이 직선 문자열이면 이벤트를 올바르게 사용하지 않는 것입니다. 이벤트 유형 상수는 컴파일 타임 유형 검사를 허용하기 위해 다양한 이벤트의 문자열 값을 보유하는 변수 일뿐입니다. – Joeflash