Каков формат параметра аргументов для ClassMirror.newInstance()?

Я совершенно готов играть с этим, пока не сделаю это правильно, но надеялся, что кто-то может дать мне подсказку. Параметр объявлен в документации (gen-dartdocs/dart-mirrors/ClassMirror/newInstance.html) как

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

В документации есть хорошая статья о формате positionalArguments и namedArguments. Тем не менее, это всего лишь немного абстрактная сторона моего текущего уровня толерантности.

Достойное обсуждение также существует на http://japhr.blogspot.com/2014/06/dart-factory-method-pattern.html Но, увы, нет примеров реальной передачи аргументов в метод.

В моем случае я хотел бы просто передать два аргумента, «заголовок» и «описание» в безымянный конструктор подкласса.

Вот мой код:

файл: 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);
}

И вот класс, который создается:

файл: 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 {
   // ...
}

Наконец, вот как называется фабрика Item. ItemElement является суперклассом собственной иерархии, подклассом которого является CodelabElement:

файл: item_element.dart:

import 'item.dart' show Item;

class ItemElement {
    Item item;
    final String itemType;

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

И элемент Codelab:

файл: codelab_element.dart

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

class CodelabElement extends ItemElement {

    final itemType = "Codelab";

    CodelabElement() : super() {}

    //...
}

А потом:

файл: main.dart

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

В настоящее время новый экземпляр Codelab возвращается из newInstance() (очень круто), но он не содержит унаследованных атрибутов title и description.

Может быть, это как-то связано с тем, что я не совсем понимаю, как использовать «расширяет» и «реализует».


person Tom Russell    schedule 05.11.2015    source источник
comment
Что вы подразумеваете под конструктором подкласса. Не могли бы вы добавить объявление класса с конструктором, который вы хотите вызвать?   -  person Günter Zöchbauer    schedule 05.11.2015
comment
Я включил довольно полный пример для всех, кто заинтересован. До сих пор ломаю голову над понятиями...   -  person Tom Russell    schedule 06.11.2015
comment
Я просто не могу понять, чего вы хотите добиться. Похоже, проблема в основном не в отражении/зеркалах, а в создании объекта в целом. Я понятия не имею, какую роль должны играть классы ItemElement и CodelabElement. Какую строку вы на самом деле передали бы как type в new Item()?   -  person Günter Zöchbauer    schedule 06.11.2015
comment
Если вы знакомы с примером Polymer и Dart Codelab на [github.com /dart-lang/polymer-and-dart-codelab] , вы увидите, что я только что удалил материал Polymer и переместил код классов Codelab* в соответствующие классы Item*. Я собираюсь опубликовать этот вопрос снова, но с другим примером.   -  person Tom Russell    schedule 06.11.2015


Ответы (1)


Это должно работать

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

и похоже

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

Только что увидел, Именованные аргументы не реализованы.

Вы можете попробовать его в DartPad.

person Günter Zöchbauer    schedule 05.11.2015
comment
Я использую Вебсторм. Выполнение вышеуказанного приводит к следующей ошибке: Необработанное исключение: нет конструктора MyClass. с соответствующими аргументами, объявленными в классе Codelab. NoSuchMethodError: неверное количество аргументов, переданных в метод с именем MyClass. Получатель: Тип: class 'MyClass' Попытка вызова: MyClass.(arg1, arg2) - person Tom Russell; 06.11.2015
comment
Похоже, Dart пытается составить вызов именованного конструктора без имени, не так ли? - person Tom Russell; 06.11.2015
comment
Ваш вопрос касается сложной темы, такой как зеркала, но ваша проблема, похоже, заключается в понимании классов, конструкторов и наследования. Ваш вопрос не показывает, чего вы пытаетесь достичь. Я даже не знаю, с чего начать дополнительные вопросы, чтобы выяснить, в чем проблема. - person Günter Zöchbauer; 12.11.2015
comment
Достаточно верно. Я постараюсь придумать лучший пример. Было бы полезно, если бы вы могли пролить свет только на сообщение об ошибке и на то, почему оно содержит '.' в MyClass.('arg1', 'arg2'). - person Tom Russell; 12.11.2015
comment
Я не думаю, что это . актуально. Вероятно, просто недосмотр, когда строка для сообщения об ошибке создается для именованных (с .) или безымянных (без) конструкторов. - person Günter Zöchbauer; 12.11.2015
comment
OK. Я был просто сбит с толку. У меня не был правильно определен конструктор MyClass. - person Tom Russell; 13.11.2015
comment
Так у тебя заработало? Рад слышать. Пожалуйста, либо примите мой ответ (отметьте галочкой под кнопками голосования вверх/вниз), если это решение вашего вопроса, либо добавьте другой ответ самостоятельно и примите его (когда вам будет разрешено через один день), чтобы этот вопрос не оставаться открытым как без ответа. Спасибо. - person Günter Zöchbauer; 13.11.2015
comment
Я получил другой, более простой пример для работы и собирался подождать, пока я не закончу этот, чтобы я мог также пересмотреть приведенный выше пример в рабочее состояние в то же время. Но я могу сделать это позже, если будут запросы на это. - person Tom Russell; 15.11.2015
comment
Я пошел дальше и разместил свой рабочий пример на stackoverflow.com/questions/33562085 (вопрос помечен как дубликат этого). - person Tom Russell; 15.11.2015