【发布时间】:2012-12-23 22:37:19
【问题描述】:
在 dart 中是否可以从字符串实例化一个类?
例如:
- javascript 中的香草:
var myObject = window[classNameString];
- 目标-C:
id myclass = [[NSClassFromString(@"MyClass") alloc] init];
【问题讨论】:
标签: dart dart-mirrors
在 dart 中是否可以从字符串实例化一个类?
例如:
var myObject = window[classNameString];
id myclass = [[NSClassFromString(@"MyClass") alloc] init];
【问题讨论】:
标签: dart dart-mirrors
您需要知道库名和类名才能正常工作。假设你都知道,下面的例子将实例化 TestClass 并在其上调用 doStuff。
library test;
import "dart:mirrors";
class TestClass {
doStuff() => print("doStuff was called!");
}
main() {
MirrorSystem mirrors = currentMirrorSystem();
LibraryMirror lm = mirrors.libraries['test'];
ClassMirror cm = lm.classes['TestClass'];
Future tcFuture = cm.newInstance('', []);
tcFuture.then((InstanceMirror im) {
var tc = im.reflectee;
tc.doStuff();
});
}
关于此解决方案的几点说明:
【讨论】:
newInstance 不返回 Future 因为实例化类可能需要异步操作,这不是真的,一切都已经加载。它返回一个Future,因为 Mirrors API 是有意异步的,因为它将在未来跨隔离区工作(并且跨隔离区通信始终是异步的)。如果您仔细检查 newInstance 调用(以及其他类似 get/setField 或 invoke 的调用),您会注意到它在后台是同步工作的。这在未来可能会明显改变。
语法已更改。 我是这样弄的
library test;
import "dart:mirrors";
class TestClass {
doStuff() => print("doStuff was called!");
}
main() {
MirrorSystem mirrors = currentMirrorSystem();
LibraryMirror lm = mirrors.libraries.values.firstWhere(
(LibraryMirror lm) => lm.qualifiedName == new Symbol('test'));
ClassMirror cm = lm.declarations[new Symbol('TestClass')];
InstanceMirror im = cm.newInstance(new Symbol(''), []);
var tc = im.reflectee;
tc.doStuff();
}
如果有更多名为 'test' 的库,这将失败。
【讨论】:
classes getter 已更改为 declarations。
这个问题一直困扰着我,直到我发现我可以实现一个粗略的 from 方法来处理 编码的 Json 对象/字符串 或 的转换飞镖映射到所需的类。
下面是一个简单的例子,它也处理空值并接受 JSON(作为 字符串 参数)
import 'dart:convert';
class PaymentDetail
{
String AccountNumber;
double Amount;
int ChargeTypeID;
String CustomerNames;
PaymentDetail({
this.AccountNumber,
this.Amount,
this.ChargeTypeID,
this.CustomerNames
});
PaymentDetail from ({ string : String, object : Map }) {
var map = (object==null) ? (string==null) ? Map() : json.decode(string) : (object==null) ? Map() : object;
return new PaymentDetail(
AccountNumber : map["AccountNumber"] as String,
Amount : map["Amount"] as double,
ChargeTypeID : map["ChargeTypeID"] as int,
CustomerNames : map["CustomerNames"] as String
);
}
}
下面是它的实现
PaymentDetail payDetail = new PaymentDetail().from(object: new Map());
PaymentDetail otherPayDetail = new PaymentDetail().from(object: {"AccountNumber": "1234", "Amount": 567.2980908});
再一次,这在整个项目中进行克隆既简单又乏味,但它适用于简单的情况。
【讨论】:
试试:
Map models = {"Player": Player.instatiate};
var player = models["Player"]();
class Player{
static instatiate() => Player();
}
【讨论】: