从 Class 对象获取 AS3 实例方法引用

发布于 2024-11-08 19:25:51 字数 1556 浏览 0 评论 0原文

class Foo {
   public function bar():void { ... }
}

var clazz:Class = Foo;

// ...enter the function (no Foo literal here)
var fun:Function = clazz["bar"]; // PROBLEM: returns null

// later
fun.call(new Foo(), ...);

执行上述操作的正确方法是什么?我想做的 Java 等效项是:

Method m = Foo.class.getMethod("bar", ...);
m.invoke(new Foo(), ...);

实际代码(带有解决方法):

class SerClass {

    public var className:String;
    public var name:String;
    private var ser:String = null;
    private var unser:Function = null;

    public function SerClass(clazz:Class):void {

        var type:XML = describeType(clazz);

        className = type.@name;

        // determine name
        name = type.factory.metadata.(@name=="CompactType").arg.(@key=="name").@value;

        // find unserializer
        var mdesc:XML = XML(type.method.metadata.(@name=="Unserialize")).parent();
        if (mdesc is XML) {
            unser = clazz[mdesc.@name];
        }

        // find serializer
        var sdesc:XML = XML(type.factory.method.metadata.(@name=="Serialize")).parent();
        if (sdesc is XML) {
            ser = sdesc.@name;
        }


    }
    public function serialize(obj:Object, ous:ByteArray):void {
        if (ser == null) throw new Error(name + " is not serializable");
        obj[ser](ous);
    }
    public function unserialize(ins:ByteArray):Object {
        if (unser == null) throw new Error(name + " is not unserializable");
        return unser.call(null, ins);
    }
}
class Foo {
   public function bar():void { ... }
}

var clazz:Class = Foo;

// ...enter the function (no Foo literal here)
var fun:Function = clazz["bar"]; // PROBLEM: returns null

// later
fun.call(new Foo(), ...);

What is the correct way to do the above? The Java equivalent of what I want to do is:

Method m = Foo.class.getMethod("bar", ...);
m.invoke(new Foo(), ...);

Actual code (with workaround):

class SerClass {

    public var className:String;
    public var name:String;
    private var ser:String = null;
    private var unser:Function = null;

    public function SerClass(clazz:Class):void {

        var type:XML = describeType(clazz);

        className = type.@name;

        // determine name
        name = type.factory.metadata.(@name=="CompactType").arg.(@key=="name").@value;

        // find unserializer
        var mdesc:XML = XML(type.method.metadata.(@name=="Unserialize")).parent();
        if (mdesc is XML) {
            unser = clazz[mdesc.@name];
        }

        // find serializer
        var sdesc:XML = XML(type.factory.method.metadata.(@name=="Serialize")).parent();
        if (sdesc is XML) {
            ser = sdesc.@name;
        }


    }
    public function serialize(obj:Object, ous:ByteArray):void {
        if (ser == null) throw new Error(name + " is not serializable");
        obj[ser](ous);
    }
    public function unserialize(ins:ByteArray):Object {
        if (unser == null) throw new Error(name + " is not unserializable");
        return unser.call(null, ins);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

翻身的咸鱼 2024-11-15 19:25:52

这里的函数 bar 仅在您的类被实例化时才存在:

var foo:Foo = new Foo()
var fun:Function = foo.bar // <-- here you can get the function from the new instance

如果您想直接访问它,您必须将其设为静态:

class Foo {
 public static function bar():void{ ... }
}

现在您可以从类 Foo 访问您的函数:

var fun:Function = Foo.bar

var clazz:Class = Foo
var fun:Function = clazz["bar"]

Here the function bar only exist when your class is instanciated :

var foo:Foo = new Foo()
var fun:Function = foo.bar // <-- here you can get the function from the new instance

if you want to access it directlty you have to make it static:

class Foo {
 public static function bar():void{ ... }
}

now you can access your function from the class Foo:

var fun:Function = Foo.bar

or

var clazz:Class = Foo
var fun:Function = clazz["bar"]
甜妞爱困 2024-11-15 19:25:52

我不确定你打算做什么。

然而,AS3Commons,尤其是反射包具有 API,可让您使用类的方法、实例和属性。

还有一些 API 方法可以动态创建某些类类型的实例并调用它们各自的方法。

干杯

I am not sure about what you are intending to do.

However AS3Commons, especially the reflect package have API's that let you work with methods, instances and properties of a class.

There are also API methods to create instances of certain class types on the fly and call their respective methods.

Cheers

手心的海 2024-11-15 19:25:52

它不是

 fun.call(new Foo(), ...);

Use 而是因为该函数不需要参数

fun.call(clazz);

第一个参数由 adobe 文档指定。
一个对象,在函数体内指定 thisObject 的值。

[编辑]
忘记指出您必须使用“new”关键字实例化一个非静态类。

var clazz:Class = new Foo();

[EDIT2]
好吧,我玩了一下,认为我得到了你想要的。

base.as

package{
  public class Base {
    public function Base() {
      trace('Base constructor')
    }
    public function someFunc( ){
      trace('worked');
    }
  }
}



//called with 
var b:Base = new Base( );// note I am not type casting to Class
var func:Function = b.someFunc;
func.call( );

It's not

 fun.call(new Foo(), ...);

Use instead since no parameters are required for the function

fun.call(clazz);

The first parameter as specified by adobe docs.
An object that specifies the value of thisObject within the function body.



[EDIT]

Forgot to point out you have to instantiate a non-static class with the "new" keyword.

var clazz:Class = new Foo();

[EDIT2]
Ok I played around and think I got what you want.

base.as

package{
  public class Base {
    public function Base() {
      trace('Base constructor')
    }
    public function someFunc( ){
      trace('worked');
    }
  }
}



//called with 
var b:Base = new Base( );// note I am not type casting to Class
var func:Function = b.someFunc;
func.call( );
ㄖ落Θ余辉 2024-11-15 19:25:52

我的解决方法是存储函数名称而不是 Function 对象。

var fun:String = "bar";

// later...
new Foo()[fun](...);

My workaround is to store the function name instead of the Function object.

var fun:String = "bar";

// later...
new Foo()[fun](...);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文