DartLang 中带有可反射库的注释的简单名称
simpleName of annotation in DartLang with reflectable lib
这真的是在 Dart 中获取注释 simpleName
的唯一方法吗?
// Annotate with this class to enable reflection.
class Reflector extends Reflectable {
const Reflector()
: super(
invokingCapability,metadataCapability
);
}
const reflector = const Reflector();
// Reflector for annotation
class MetaReflector extends Reflectable {
const MetaReflector()
: super(metadataCapability);
}
const metareflector = const MetaReflector();
@metareflector
class MyAnnotation {
final String name;
const MyAnnotation(this.name);
}
@reflector // This annotation enables reflection on A.
class A {
final int a;
A(this.a);
int valueFunction() => a;
int get value => a;
@MyAnnotation("James Bond")
String nameFunction() => "Mike";
}
最后一行 returns SimpleName - 似乎有点复杂?
test('> Annotation', () {
final A a = new A(10);
final InstanceMirror im = reflector.reflect(a);
final ClassMirror cm = im.type;
Map<String, MethodMirror> instanceMembers = cm.instanceMembers;
expect(instanceMembers.keys.contains("valueFunction"),isTrue);
expect(instanceMembers.keys.contains("value"),isTrue);
expect(instanceMembers.keys.contains("nameFunction"),isTrue);
final MethodMirror mm = instanceMembers["nameFunction"];
expect(mm.isRegularMethod,isTrue);
expect(mm.metadata.length,1);
final x = mm.metadata.first;
expect(x,new isInstanceOf<MyAnnotation>());
expect((x as MyAnnotation).name,"James Bond");
final InstanceMirror imAnnotation = metareflector.reflect(x);
final ClassMirror cmAnnotation = imAnnotation.type;
expect(cmAnnotation.simpleName,"MyAnnotation");
}); // end of 'Annotation' test
在测试 expect(x,new isInstanceOf<MyAnnotation>());
时,您基本上已经使计算结果变得微不足道:静态已知 MyAnnotation
实例的 class 的名称是 "MyAnnotation"
.
但是,如果您的实际使用上下文没有静态地提交注释类型,那么您将需要一种更动态的方法。获取元数据对象的 class 镜像(正如您所做的那样)是一种可行的通用方法,您还需要类似 metaReflector
的东西来获得对查找 class 的支持镜子。顺便说一句,我不明白你为什么需要 metaReflector
上的 metadataCapability
,但我希望它需要 typeCapability
.
请注意,最新版本的 reflectable 需要 declarationsCapability
才能使用 instanceMembers
和 staticMembers
(在没有该功能的情况下支持它们是不正常的)。
如果你能让事情变得更静态一点,那么你可以选择一些中间解决方案:你可以将你的元数据组织成一个子类型层次结构,这样你需要处理的那种元数据的每个实例都会有一个 nameOfClass
方法,或者您可以创建一个 Map<Type, String>
来将您将处理的每种类型的元数据翻译成它的名称,或者您甚至可以(请原谅我;-)使用 toString()
这将揭示class 未覆盖 Object
.
中的 toString()
的任何对象的名称
最后,如果您想以 "somewhat dynamic" 的方式处理元数据,我建议您考虑直接使用 Type
值:您可以查找 x.runtimeType
并使基于与 MyAnnotation
比较的决策就像您可以根据与字符串 "MyAnnotation"
的比较做出决策一样,只有当您想要做像 "any class whose name matches this regex will do here" 这样的文本时,您才能从中获得任何东西通过字符串。
(应该说 runtimeType
有点昂贵,因为它会导致在运行时保留额外的数据,尤其是对于 dart2js,但是当您使用 reflectable 时已经需要这些数据)。
这真的是在 Dart 中获取注释 simpleName
的唯一方法吗?
// Annotate with this class to enable reflection.
class Reflector extends Reflectable {
const Reflector()
: super(
invokingCapability,metadataCapability
);
}
const reflector = const Reflector();
// Reflector for annotation
class MetaReflector extends Reflectable {
const MetaReflector()
: super(metadataCapability);
}
const metareflector = const MetaReflector();
@metareflector
class MyAnnotation {
final String name;
const MyAnnotation(this.name);
}
@reflector // This annotation enables reflection on A.
class A {
final int a;
A(this.a);
int valueFunction() => a;
int get value => a;
@MyAnnotation("James Bond")
String nameFunction() => "Mike";
}
最后一行 returns SimpleName - 似乎有点复杂?
test('> Annotation', () {
final A a = new A(10);
final InstanceMirror im = reflector.reflect(a);
final ClassMirror cm = im.type;
Map<String, MethodMirror> instanceMembers = cm.instanceMembers;
expect(instanceMembers.keys.contains("valueFunction"),isTrue);
expect(instanceMembers.keys.contains("value"),isTrue);
expect(instanceMembers.keys.contains("nameFunction"),isTrue);
final MethodMirror mm = instanceMembers["nameFunction"];
expect(mm.isRegularMethod,isTrue);
expect(mm.metadata.length,1);
final x = mm.metadata.first;
expect(x,new isInstanceOf<MyAnnotation>());
expect((x as MyAnnotation).name,"James Bond");
final InstanceMirror imAnnotation = metareflector.reflect(x);
final ClassMirror cmAnnotation = imAnnotation.type;
expect(cmAnnotation.simpleName,"MyAnnotation");
}); // end of 'Annotation' test
在测试 expect(x,new isInstanceOf<MyAnnotation>());
时,您基本上已经使计算结果变得微不足道:静态已知 MyAnnotation
实例的 class 的名称是 "MyAnnotation"
.
但是,如果您的实际使用上下文没有静态地提交注释类型,那么您将需要一种更动态的方法。获取元数据对象的 class 镜像(正如您所做的那样)是一种可行的通用方法,您还需要类似 metaReflector
的东西来获得对查找 class 的支持镜子。顺便说一句,我不明白你为什么需要 metaReflector
上的 metadataCapability
,但我希望它需要 typeCapability
.
请注意,最新版本的 reflectable 需要 declarationsCapability
才能使用 instanceMembers
和 staticMembers
(在没有该功能的情况下支持它们是不正常的)。
如果你能让事情变得更静态一点,那么你可以选择一些中间解决方案:你可以将你的元数据组织成一个子类型层次结构,这样你需要处理的那种元数据的每个实例都会有一个 nameOfClass
方法,或者您可以创建一个 Map<Type, String>
来将您将处理的每种类型的元数据翻译成它的名称,或者您甚至可以(请原谅我;-)使用 toString()
这将揭示class 未覆盖 Object
.
toString()
的任何对象的名称
最后,如果您想以 "somewhat dynamic" 的方式处理元数据,我建议您考虑直接使用 Type
值:您可以查找 x.runtimeType
并使基于与 MyAnnotation
比较的决策就像您可以根据与字符串 "MyAnnotation"
的比较做出决策一样,只有当您想要做像 "any class whose name matches this regex will do here" 这样的文本时,您才能从中获得任何东西通过字符串。
(应该说 runtimeType
有点昂贵,因为它会导致在运行时保留额外的数据,尤其是对于 dart2js,但是当您使用 reflectable 时已经需要这些数据)。