dart, how to define a class so it can be used as a class attribute?


I’ve seen in polymer.dart they have:

class CustomTag {
  final String tagName;
  const CustomTag(this.tagName);

but how does that interact with the rest of the code? from just the code above I can’t see how using @CustomTag('my-tag') actually does anything but creates a CustomTag which is then garbage collected since nothing is referencing it.


To answer the question in the title; these are called Annotations; they are simply const constructors.

To answer the second question; these are usually used for tooling (eg. @deprecated) or rewriting via a Transformer. You can access them at runtime using mirrors, but that’s probably not practical/advisable for a production web app that gets converted to JavaScript.

Here’s some sample code taken from this answer

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) {
      } else if (reflectee.runtimeType == annotation) {

  return result;

class 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']

Answered By – Danny Tuppeny

Answer Checked By – Senaida (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *