6

呼び出されるたびにメッセージをログに記録するメソッドがあります。このログ メッセージに、メソッドが直接呼び出されsuperたのか、子クラスで呼び出されたのかを示してほしいと思います。

class DoerOfWork {
    public function doWork():void {
        var calledWithSuper:Boolean; 

        calledWithSuper = ???;

        trace("doWork called" + (calledWithSuper ? " (with super)." : "."));
    }
}

class SlowerDoerOfWork extends DoerOfWork {
    public override function doWork():void {
        for (var i:Number = 0; i < 321684; i++) {
            // wait a moment
        }
        super.doWork();
    }
}

と比較することで、 のクラスがthisの実装をオーバーライドしたかどうかを判断できるようになることを望みました。doWorkthis.doWorkDoerOfWork.prototype.doWork

残念ながら、これは不可能です。バインドされていないメソッドは、ActionScript のどこからでもアクセスできません (仕様には、関数クロージャーとバインドされたメソッドの 2 種類の関数がリストされています)。MethodClosure2 つが同じメソッドのバインドされたコピーであるかどうかを識別できるインスタンスのプロパティさえありません。

メソッドがオーバーライドされているかどうか、または他のメソッドを使用して、現在実行中の ActionScript メソッドが呼び出されたか、superまたは直接呼び出されたかを確認するにはどうすればよいですか?

4

2 に答える 2

3

を使用する場合flash.utils.describeType()は、必要な情報が含まれています。

<type name="Main.as$1::SlowerDoerOfWork" base="Main.as$1::DoerOfWork"
      isDynamic="false" isFinal="false" isStatic="false">
  <extendsClass type="Main.as$1::DoerOfWork"/>
  <extendsClass type="Object"/>
  <method name="doWork" declaredBy="Main.as$1::SlowerDoerOfWork"
          returnType="void">
    <metadata name="__go_to_definition_help">
      <arg key="pos" value="1170"/>
    </metadata>
  </method>
  <metadata name="__go_to_definition_help">
    <arg key="pos" value="1103"/>
  </metadata>
</type>

XML の eachのdeclaredBy属性は<method>と同じ形式を使用しており、flash.utils.getQualifiedClassNameこれらを比較して、実装がオーバーライドされたかどうかを判断できます。

class DoerOfWork {
    public function doWork():void {
        var calledWithSuper:Boolean; 

        var currentImplementationFrom:String
          = flash.utils.describeType(this).method.(@name=="doWork").@declaredBy;
        var thisImplementationFrom:String
          = flash.utils.getQualifiedClassName(DoerOfWork);

        calledWithSuper = currentImplementationFrom != thisImplementationFrom;

        trace("doWork called" + (calledWithSuper ? " (with super)." : "."));
    }
}
于 2013-03-05T01:22:32.393 に答える
3

現在実行中の関数への参照を として取得できますarguments.callee。メソッドから、これは の にMethodClosureなりDoerOfWork().doWork()ますthis。オーバーライドされていない場合doWork()、これは と等しくなりthis.doWorkます。

class DoerOfWork {
    public function doWork():void {
        var calledWithSuper:Boolean; 

        calledWithSuper = this.doWork == arguments.callee;

        trace("doWork called" + (calledWithSuper ? " (with super)." : "."));
    }
}

非厳密モードで実行している場合、明らかに、これにより現在の関数の引数カウントのチェックが無効になります。(私はこれを自分で確認していません。IntelliJ で厳密モードを無効にする方法さえわかりません。)

于 2013-03-05T01:22:16.483 に答える