在Dart中如何从字符串/符号创建一个对象实例而不需要类?

3

我知道可以像这个链接中所示创建一个符号的实例:

在Dart中从字符串创建对象的实例?

但是对我来说这并不起作用,因为我想做的是在没有类的情况下创建实例。

这个问题是由于我有一个带有内部列表的类所引起的:

class MyNestedClass {
  String name;
}

class MyClass {
  int i, j;
  String greeting;
  List<MyNestedClass> myNestedClassList;
}

我想将一个地图转换成这个类:

   {
        "greeting": "hello, there",
        "i": 3,
        "j": 5,
        "myNestedClassList": [
           {
             "name": "someName1"
           },{
             "name": "someName2"
           }
        ]
    }

现在我正在做这样的事情:

 static void jsonToObject(String jsonString, Object object) {
    Map jsonMap = JSON.decode(jsonString); //Convert the String to a map
    mapToObject(jsonMap, object); //Convert the map to a Object
  }

  static void mapToObject(Map jsonMap, Object object) {
    InstanceMirror im = reflect(object); //get the InstanceMirror of the object
    ClassMirror cm = im.type; //get the classMirror of the object

    jsonMap.forEach((fieldNameStr, fieldValue) { // For each element in the jsonMap
      var fieldName = new Symbol(fieldNameStr); // convert the fieldName in the Map to String

      if (isPrimitive(fieldValue)) { // if fieldValue is primitive (num, string, or bool
              im.setField(fieldName, fieldValue); //set the value of the field using InstanceMirror
      } else if (fieldValue is List) { // else if the fieldValue is a list
          ClassMirror listCm = (cm.declarations[fieldName] as VariableMirror).type; //get the class mirror of the list
          var listReflectee = listCm.newInstance(const Symbol(''), []).reflectee; //create an instance of the field

          for(var element in fieldValue) { //for each element in the list
            if(!isPrimitive(element)) { // if the element in the list is a map (i.e not num, string or bool)
               var listType = listCm.typeArguments[0]; //get the TypeMirror of the list (i.e MyNestedClass from List<MyNestedClass>)

               //This is the line that doesn't work correctly
               //It should be something like:
               //
               //     ClassMirror.fromSymbol(listType.simpleName).newInstance(const Symbol(''), []);
               //
               var listObject = (listType as ClassMirror).newInstance(const Symbol(''), []); //create an instance of the specified listType

               mapToObject(element, listObject); //convert the element to Object
            }
            listReflectee.add(element); //add the element to the list
          };
      } else { //else (the field value is a map
        ClassMirror fieldCm = (cm.declarations[fieldName] as VariableMirror).type; // get the field ClassMirror from the parent declarations
        var reflectee = fieldCm.newInstance(const Symbol(''), []).reflectee; //create an instance of the field
        mapToObject(fieldValue, reflectee); // convert the fieldValue, which is a map, to an object
        im.setField(fieldName, reflectee); // set the value of the object previously converted to the corresponding field
      }
    });
  }

正如您所看到的,实际上没有起作用的行是:

var listType = listCm.typeArguments[0]; //get the TypeMirror of the list (i.e MyNestedClass from List<MyNestedClass>)
var listObject = (listType as ClassMirror).newInstance(const Symbol(''), []); //create an instance of the specified listType

因为他们是在 localClassMirror 上创建一个实例,而不是在 MyNestedClass 上。我正在寻找一个类似于以下的方法:

 ClassMirror.fromSymbol(listType.simpleName).newInstance(const Symbol(''), []);

您可以在下面的链接中查看完整的源代码: DSON源代码
1个回答

1
如果您有类的完全限定名称,您应该能够使用libraryMirror找到类型,然后它应该类似于您链接的问题来创建一个实例。我自己还没有做过这个,手头也没有代码。
另一种方法是在应用程序初始化时创建一个映射表,在其中使用名称或ID注册支持的类型,并在此映射表中查找类型(这类似于Go中的操作)。
参见:如何从Dart库字符串或文件调用类

链接问题答案中的代码应该是您要寻找的。我更新了代码以反映自回答编写以来的API更改。 - Günter Zöchbauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接