10

noSuchMethod() のルックアップを使用して、Map で動的プロパティをバックアップできるようにしたいと考えています。ただし、最新の変更により、着信プロパティ参照名が使用できなくなります。名前に文字列ではなくシンボルを使用する必要があるミニフィケーションのシナリオは理解できますが、これによりシリアライズ可能な動的プロパティの実装が難しくなります。誰でもこの問題にアプローチする方法について良いアイデアを持っていますか?

  • 文字列名はミニファイアの呼び出し間で固定されていないため、文字列名は使用できません。(これはシリアライゼーションを完全に壊します)
4

4 に答える 4

12

で元の名前にアクセスできますMirrorSystem.getName(symbol)

したがって、動的クラスは次のようになります。

import 'dart:mirrors';

class A {
  final _properties = new Map<String, Object>();

  noSuchMethod(Invocation invocation) {
    if (invocation.isAccessor) {
      final realName = MirrorSystem.getName(invocation.memberName);
      if (invocation.isSetter) {
        // for setter realname looks like "prop=" so we remove the "="
        final name = realName.substring(0, realName.length - 1);
        _properties[name] = invocation.positionalArguments.first;
        return;
      } else {
        return _properties[realName];
      }
    }
    return super.noSuchMethod(invocation);
  }
}

main() {
  final a = new A();
  a.i = 151;
  print(a.i); // print 151
  a.someMethod(); // throws
}
于 2013-05-02T07:37:05.483 に答える
1

次のようなことができます。

import 'dart:json' as json;

main() {
    var t = new Thingy();
    print(t.bob());
    print(t.jim());
    print(json.stringify(t));
}

class Thingy {
    Thingy() {
        _map[const Symbol('bob')] = "blah";
        _map[const Symbol('jim')] = "oi";
    }

    final Map<Symbol, String> _map = new Map<Symbol, String>();

    noSuchMethod(Invocation invocation) {
        return _map[invocation.memberName];
    }

    toJson() => {
        'bob': _map[const Symbol('bob')],
        'jim': _map[const Symbol('jim')]};
}

更新 - 動的な例:

import 'dart:json' as json;

main() {
    var t = new Thingy();
    t.add('bob', 'blah');
    t.add('jim', 42);
    print(t.bob());
    print(t.jim());
    print(json.stringify(t));
}

class Thingy {
    final Map<Symbol, String> _keys = new Map<Symbol, String>();
    final Map<Symbol, dynamic> _values = new Map<Symbol, dynamic>();

    add(String key, dynamic value) {
        _keys[new Symbol(key)] = key;
        _values[new Symbol(key)] = value;
    }

    noSuchMethod(Invocation invocation) {
        return _values[invocation.memberName];
    }

    toJson() {
        var map = new Map<String, dynamic>();
        _keys.forEach((symbol, name) => map[name] = _values[symbol]);
        return map;
    }
}
于 2013-05-02T05:36:58.880 に答える