How to implement dynamic properties in Dart?

You can access the original name with MirrorSystem.getName(symbol)

So a dynamic class could look like :

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
}

You could do something like this:

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

Update - dynamic example:

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

Tags:

Dart