【问题标题】:In Dart, can you retrieve metadata (e.g., annotations) at runtime using reflection?在 Dart 中,您可以在运行时使用反射检索元数据(例如注释)吗?
【发布时间】:2023-03-20 12:07:01
【问题描述】:

如果是这样,这是如何实现的?如果没有,是否有计划在未来的 Dart 版本中支持这一点?我主要指的是您自己创建的自定义注释。

在此文档链接https://www.dartlang.org/docs/spec/latest/dart-language-specification.html#h.d0rowtffuudf 中,它说:“元数据与紧跟在元数据之后的程序构造 p 的抽象语法树相关联,假设 p 本身不是元数据或注释。元数据可以在运行时通过反射调用,只要带注释的程序构造 p 可以通过反射访问。

自 M3 版本起尚未实现对元数据的反射访问。"

谢谢。

【问题讨论】:

  • 您问“自 M3 版本起,对元数据的反射访问尚未实现”???? M3 发布是很久以前的事了。它于 2013 年 2 月 20 日发布。您必须将 Dart SDK 更新到最新版本。

标签: annotations dart dart-mirrors


【解决方案1】:

是的,您可以使用 dart:mirrors 检索注释:

import 'dart:mirrors';

@override
class A {}

main(){
  TypeMirror typeOfA = reflectType(A);
  // or reflectType(a.runtimeType) if a is an instance of A

  // getting metadata of the class
  List<InstanceMirror> metadatas = typeOfA.metadata;
  for (InstanceMirror m in metadatas) {
    ClassMirror cm = m.type;
    // here you get the Class of the annotation
  }
}

【讨论】:

    【解决方案2】:

    用于理解的示例代码。

    import "dart:mirrors";
    
    void main() {
      var object = new Class1();
      var classMirror = reflectClass(object.runtimeType);
      // Retrieve 'HelloMetadata' for 'object'
      HelloMetadata hello = getAnnotation(classMirror, HelloMetadata);
      print("'HelloMetadata' for object: $hello");
    
      // Retrieve 'Goodbye' for 'object.method'
      var methodMirror = (reflect(object.method) as ClosureMirror).function;
      Goodbye goodbye = getAnnotation(methodMirror, Goodbye);
      print("'Goodbye' for object: $goodbye");
    
      // Retrieve all 'Goodbye' for 'object.method'
      List<Goodbye> goodbyes = getAnnotations(methodMirror, Goodbye);
      print("'Goodbye's for object.method': $goodbyes");
    
      // Retrieve all metadata for 'object.method'
      List all = getAnnotations(methodMirror);
      print("'Metadata for object.method': $all");
    }
    
    Object getAnnotation(DeclarationMirror declaration, Type annotation) {
      for (var instance in declaration.metadata) {
        if (instance.hasReflectee) {
          var reflectee = instance.reflectee;
          if (reflectee.runtimeType == annotation) {
            return reflectee;
          }
        }
      }
    
      return null;
    }
    
    List getAnnotations(DeclarationMirror declaration, [Type annotation]) {
      var result = [];
      for (var instance in declaration.metadata) {
        if (instance.hasReflectee) {
          var reflectee = instance.reflectee;
          if (annotation == null) {
            result.add(reflectee);
          } else if (reflectee.runtimeType == annotation) {
            result.add(reflectee);
          }
        }
      }
    
      return result;
    }
    
    @HelloMetadata("Class1")
    class Class1 {
      @HelloMetadata("method")
      @Goodbye("method")
      @Goodbye("Class1")
      void method() {
      }
    }
    
    class HelloMetadata {
      final String text;
      const HelloMetadata(this.text);
      String toString() => "Hello '$text'";
    }
    
    class Goodbye {
      final String text;
      const Goodbye(this.text);
      String toString() => "Goodbye '$text'";
    }
    

    输出:

    'HelloMetadata' for object: Hello 'Class1'
    'Goodbye' for object: Goodbye 'method'
    'Goodbye's for object.method': [Goodbye 'method', Goodbye 'Class1']
    'Metadata for object.method': [Hello 'method', Goodbye 'method', Goodbye 'Class1']
    

    附言

    如果 Dart 支持我建议使用此代码的泛型方法。

    T getAnnotation<T>(DeclarationMirror declaration) {
      for (var instance in declaration.metadata) {
        if (instance.hasReflectee) {
          var reflectee = instance.reflectee;
          if (reflectee.runtimeType == T) {
            return reflectee;
          }
        }
      }
    
      return null;
    }
    

    并使用泛型方法检索元数据。

    var goodbye = getAnnotation<Goodbye>(methodMirror);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多