Привести JSON как пользовательский объект ActionScript? - PullRequest
6 голосов
/ 22 мая 2009

Здравствуйте, мне было интересно, можно ли привести мою строку JSON как пользовательский объект?

в основном:

var customObject:CustomObject = JSON.decode(evt.result as String) as CustomObject;

С уважением Adlertz

Ответы [ 5 ]

4 голосов
/ 23 мая 2009

В AS3 нельзя привести динамический объект к пользовательскому классу, используя как или CustomClass (customObject) .

Однако вы можете использовать некоторые простые приемы в качестве обходного пути. Например, вы могли бы объявить конструктор для вашего пользовательского класса, принимающий Object и инициализирующий его члены со свойствами объекта.

Затем вы бы использовали:

var customObject:CustomClass = new CustomClass(JSON.decode(evt.result as String));

PS. Что касается комментариев, это не так для каждого языка ... Я думаю, это делает его actioncript специфичным .

3 голосов
/ 23 мая 2009

По сути, это невозможно. И это не имеет ничего общего с ActionScript. В большинстве других языков у вас такая же проблема, так как на левой стороне у вас есть анонимный объект, если язык поддерживает какую-либо такую ​​вещь, или хеш. Тем не мение. Существуют разные решения, это одно, которое может обрабатывать несколько вещей:

package  {
    public class ObjectUtils {
        public static function createInstance(constructor:Class):* {
            var ret:*;
            switch (describeType(to).factory.constructor.parameter.(@optional == "false").length()) {
                case 0: ret = new to(); break;
                case 1: ret = new to(null); break;
                case 2: ret = new to(null, null); break;
                case 3: ret = new to(null, null, null); break;
                case 4: ret = new to(null, null, null, null); break;
                case 5: ret = new to(null, null, null, null, null); break;
                case 6: ret = new to(null, null, null, null, null, null); break;
                case 7: ret = new to(null, null, null, null, null, null, null); break;
                case 8: ret = new to(null, null, null, null, null, null, null, null); break;
                case 9: ret = new to(null, null, null, null, null, null, null, null, null); break;          
                default: throw new Error("no implementation for instantiating classes that require more than 9 constructor arguments");
            }
            return ret;
        }
        public static function castAnonymous(obj:Object, to:Class):* {
            var ret = createInstance(obj);
            for (var name:String in obj)
                try {
                    ret[name] = obj[name];
                }
                catch (e:Error) {
                    throw new Error("error trying to assign value " + obj[name] + " to property " + name + " on " + ret + ". reason: " + e);
                }
            return ret;
        }               
    }   
}

ограничения:

  1. потерпит неудачу, если ваш класс паникует, если он спамит пустыми значениями при конструировании или если конструктору требуется более 9 аргументов
  2. не делает и не может выполнять рекурсию, поэтому может просто назначать анонимные объекты или массивы свойствам возвращенного экземпляра

надеюсь, это все равно поможет;)

Greetz

back2dos

2 голосов
/ 10 ноября 2013

есть способ

as3-vanilla lib на github, очень хорошо:)

https://github.com/jonnyreeves/as3-vanilla

2 голосов
/ 08 декабря 2012

На самом деле - вы можете обойти это ограничение, используя встроенный синтаксический анализатор и переопределив метод JSON.parse и воспользовавшись областью действия анонимной функции для доступа к объекту в родительской функции.

Например - посмотрите этот фрагмент кода

public dynamic class MutatorData extends Object
{
    public var DisplayName:String;
    public var PropertyName:String;
}

public function parseData( data:String )
{
    var mutator:MutatorData = new MutatorData();

    JSON.parse( data,
        function (k, v) {
        mutator[k] = v;
        });
}

С примером кода, как есть - класс MutatorData должен быть объявлен как динамический, что ПОЧТИ почти исключает цель создания класса для него. Вы не сможете помешать другим кодировщикам добавлять свойства к нему, орфографические ошибки в вашей строке JSON станут свойствами объекта. Даже в этом случае вы получите некоторые подсказки RTTI и кода в IDE, что поможет предотвратить ошибки кодера.

Но было бы просто написать собственную версию метода разбора, которая работала бы с конечным (не динамическим) классом.

В проекте, над которым я сейчас работаю - производительность памяти и времени выполнения критически важна, и мы предпочитаем использовать пользовательские парсеры по следующим причинам:

1) Это позволяет нам изменять строго типизированный объект на начальном этапе и отказаться от копирования данных во временный универсальный объект.

2) Мы можем встроить валидатор прямо в синтаксический анализатор, выбрасывая ошибки времени выполнения по мере необходимости, чтобы уведомить программу, что мы получили неверные данные JSON.

0 голосов
/ 17 декабря 2009

Вы не можете кастовать пользовательские объекты из динамических объектов. Но вы можете расширить JSON-декодер из as3corelib. Я сделал это именно по этой причине. Когда я декодирую json-String, я передаю имя класса закодированного объекта. При небольшом использовании отражения вы получаете строго типизированный пользовательский объект. Конечно, вам нужно знать имя класса закодированного объекта перед декодированием ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...