Получить ссылку метода экземпляра AS3 из объекта класса

117
10

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(), ...);


Каков правильный способ сделать это? Явный эквивалент того, что я хочу сделать:


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

спросил(а) 2021-01-25T19:42:40+03:00 4 месяца, 4 недели назад
1
Решение
77

Здесь функциональная панель существует только тогда, когда ваш класс инстанцируется:


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"]

ответил(а) 2021-01-25T19:42:40+03:00 4 месяца, 4 недели назад
64

Я не уверен, что вы собираетесь делать.


Однако AS3Commons, особенно пакет отражения имеет API, который позволяет работать с методами, экземплярами и свойствами класса.


Существуют также методы API для создания экземпляров определенных типов классов "на лету" и вызова их соответствующих методов.


Приветствия

ответил(а) 2021-01-25T19:42:40+03:00 4 месяца, 4 недели назад
44

Это не


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

Используйте вместо этого, поскольку для функции

не требуются никакие параметры,
fun.call(clazz);

Первый параметр, указанный в adobe docs.

Объект, который задает значение thisObject внутри тела функции.




[EDIT]

Забыл указать, что вам нужно создать экземпляр нестатического класса с ключевым словом "новое".


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

ответил(а) 2021-01-25T19:42:40+03:00 4 месяца, 4 недели назад
-4

Мое обходное решение заключается в сохранении имени функции вместо объекта Function.

var fun:String = "bar";

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

ответил(а) 2021-01-25T19:42:40+03:00 4 месяца, 4 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема