Преобразование динамического типа с зеркалами

Проблема:

Возможно ли динамическое приведение к типу?

Например, возможно ли это, используя зеркала:

var reflectee = im.getField(simpleName).reflectee;

var converted = testVal as reflectee.runtimeType;

Контекст: я хочу создать класс Mixin, который определяет метод validate:

abstract class Validatable {
  bool validate(Map document) {
  }
}

Он будет перебирать переменные, определенные для класса, в котором они смешаны, и проверяет, относятся ли переменные в документе к тому же типу.

Теперь он работает с получением runtimeType соответствующих переменных, но он очень ограничен, поскольку не выполняет приведение типов. Например:

var a = 1.1;
var b = 1;
print(a.runtimeType == b.runtimeType); // false

Было бы лучше проверить с as, но я не вижу, как заставить это работать. Потому что:

a = b;
print(a.runtimeType); // int

а не вдвое, как можно было бы ожидать.

Является ли это возможным?


person tusj    schedule 03.04.2014    source источник


Ответы (1)


Вы могли бы использовать

import 'dart:mirrors';

class A {

}

class B extends A {

}

class C extends A {

}

void main(args) {
  var a = 1.1;
  var b = 1;
  var x = reflect(b);
  print(x.type.isSubtypeOf(reflectType(num)));
  print(x.type.isAssignableTo(reflectType(num)));
  print(x.type.isAssignableTo(reflectType(double)));

  var myb = new B();

  print(reflect(myb).type.isSubtypeOf(reflectType(A)));
  print(reflect(myb).type.isAssignableTo(reflectType(A)));
  print(reflect(myb).type.isAssignableTo(reflectType(C)));    
}
person Günter Zöchbauer    schedule 03.04.2014
comment
Я думаю, что isSubtypeOf и isAssignableTo довольно новые. - person Günter Zöchbauer; 03.04.2014
comment
Мне просто интересно, как быть с implements. Потому что тогда, строго говоря, речь не идет о подтипе. - person tusj; 03.04.2014
comment
Я пробовал: B implements D создает подтип myb и назначает его D. Если он реализует интерфейс, он может be этого типа. Я думаю, что isSubtypeOf включает is. - person Günter Zöchbauer; 03.04.2014
comment
У меня была версия 1.1.3 SDK, и я вижу, что версия 1.2 вышла, так что это дополнение было новым. - person tusj; 03.04.2014
comment
1.3.0 выйдет очень скоро. - person Günter Zöchbauer; 03.04.2014
comment
Я проверил еще несколько вызовов новых функций с типами Map и ObservableMap, где ObservableMap реализует Map. Согласно документации, верно, как вы говорите, что isSubclass проверяет is. Однако ни в одном из методов не упоминается, что они проверяют as, и ни один из ObservableMap isAssignableTo Map не сообщает об истинности. Может быть, 1.3 привнесет какие-то изюминки? - person tusj; 03.04.2014
comment
Я попробовал это с ObservableMap и подтипом и назначаемым отчетом true (версия Dart VM: 1.3.0-dev.7.10 (четверг, 3 апреля, 01:00:43 2014 г.) на linux_x64) - person Günter Zöchbauer; 04.04.2014
comment
Я также протестировал v1.3 сейчас. Он по-прежнему сообщает мне ложь. Вот код, который я использую: (pastebin.com/BVBj56Mm) - person tusj; 04.04.2014
comment
Мне это тоже не помогло var aa = reflect(a).type;. Кажется, вам нужно получить TypeMirror с помощью reflectType(x), чтобы он заработал. Мне еще предстоит выяснить, в чем разница. - person Günter Zöchbauer; 04.04.2014
comment
Хорошо я понял. Когда вы используете reflect(new Map()).type, вы получаете ClassMirror on '_LinkedHashMap', вместо reflectType(Map) вы получаете ClassMirror on 'Map'. Вы не можете назначить Map на LinkedHashMap, потому что LinkedHashMap более специализированный. Фактический тип среды выполнения отличается от типа, используемого в new. - person Günter Zöchbauer; 04.04.2014
comment
Если я сделаю это: var AA = reflectType(a.runtimeType); и проверю на то же самое, я все равно получу только false. С обеими версиями SDK. Я обновил pastebin, чтобы показать, что именно я делаю. - person tusj; 04.04.2014
comment
когда a является экземпляром ObservableMap, выводится true: ` var AA = ReflectType(a.runtimeType); print(AA.isAssignableTo(reflectType(Map))); print(reflectType(Map).isAssignableTo(AA)); ` - person Günter Zöchbauer; 04.04.2014
comment
О да. Код, который я разместил, проверяет базовый тип, а не саму карту. Итак, вернемся к проблеме as, не зная явно типов ни одного из объектов и выясняя, реализует ли один другой. - person tusj; 04.04.2014
comment
Я думаю, вам нужно просто проверить все типы (aa, aa.mixin, aa.superinterfaces), если они назначаемы. - person Günter Zöchbauer; 04.04.2014