What is the format of the “arguments” parameter to ClassMirror.newInstance()?

帅比萌擦擦* 提交于 2019-12-23 04:48:10

问题


I'm perfectly willing to play with this until I get it right, but was hoping someone might give me a hint. The parameter is declared in the docs (gen-dartdocs/dart-mirrors/ClassMirror/newInstance.html) as

InstanceMirror newInstance(Symbol constructorName,
                      List positionalArguments,
                      [Map<Symbol,dynamic> namedArguments]);

There is a nice writeup on the format of positionalArguments and namedArguments in the docs. However, it is just a little on the abstract side of my current tolerance level.

A decent discussion also exists at http://japhr.blogspot.com/2014/06/dart-factory-method-pattern.html But, alas, no examples of actually passing args into the method.

In my case, I would like to simply pass two args, "title" and "description" into an unnamed subclass constructor.

Here's my code so far:

file: item.dart

import 'dart:mirrors';

abstract class Item {

    String title;
    String description;

    factory Item(String type) {
      MirrorSystem libs = currentMirrorSystem();
      LibraryMirror lib = libs.findLibrary(new Symbol('app.models'));
      Map<Symbol, Mirror> classes = lib.declarations;
      // To do: handle exception if class not found
      ClassMirror cls = classes[new Symbol(type)];
      // TODO:
      //  verify each subclass has no-arg ctor
      //  determ how to pass args to ctor.
      InstanceMirror inst = cls.newInstance(new Symbol(''), []);
      return inst.reflectee;
    }

    // conflicts w/ Item factory
//  Item(this.title, this.description);
}

And here's the class that gets instantiated:

file: model.dart

library app.models;

import 'item.dart' show Item;

/// The barebones model for a codelab. Defines constants used for validation.
class Codelab implements Item {
   // ...
}

Finally, here is how the Item factory is called. ItemElement is the superclass of its own hierarchy, subclassed by CodelabElement:

file: item_element.dart:

import 'item.dart' show Item;

class ItemElement {
    Item item;
    final String itemType;

    ItemElement() {
      item = new Item(itemType);
    }
    // ...
}

And CodelabElement:

file: codelab_element.dart

import 'model.dart' show Codelab;
import 'item_element.dart' show ItemElement;

class CodelabElement extends ItemElement {

    final itemType = "Codelab";

    CodelabElement() : super() {}

    //...
}

And then:

file: main.dart

void main() {
    var element = new CodelabElement();
}

Currently, the new Codelab instance is returned from newInstance() (very cool), but it doesn't contain the inherited 'title' and 'description' attrs.

Maybe it has something to do with my being unclear on the usage of "extends" and "implements".


回答1:


This should work

cls.newInstance(new Symbol(''), ['a', 1] /*, 
    {#arg1Name: 'arg1Value', #arg2Name: 'arg2Value'}*/ );

and is like

new MyClass('a', 1, arg1Name: 'arg1Value' /*, arg2Name: 'arg2Value'*/); 

Just saw, Named arguments are not implemented.

You can try it in DartPad



来源:https://stackoverflow.com/questions/33562085/how-are-arguments-passed-into-the-parameter-list-of-classmirror-newinstance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!