Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Under what circumstances does reflectClass(o.runtimeType) return a different result from reflect(o).type?

from the dartdocs for InstanceMirror.type:

"Returns a mirror on the actual class of the reflectee. The class of the reflectee may differ from the object returned by invoking runtimeType on the reflectee."

so under what circumstances does reflectClass(o.runtimeType) return a different result from reflect(o).type?

I have tried with example code:

import 'dart:mirrors';

class A{}

void main() {

  var string = "str";
  var boolean = true;
  var integer = 5;
  var map = {};
  var list = [];
  var custom = new A();

  var strRunT = string.runtimeType;
  var strRefT = reflect(string).type.reflectedType;
  var boolRunT = boolean.runtimeType;
  var boolRefT = reflect(boolean).type.reflectedType;
  var intRunT = integer.runtimeType;
  var intRefT = reflect(integer).type.reflectedType;
  var mapRunT = map.runtimeType;
  var mapRefT = reflect(map).type.reflectedType;
  var listRunT = list.runtimeType;
  var listRefT = reflect(list).type.reflectedType;
  var cusRunT = custom.runtimeType;
  var cusRefT = reflect(custom).type.reflectedType;

  print('string');
  print('runtimeType = $strRunT');
  print('reflectedType = $strRefT');
  print('runT == refT = ${strRunT == strRefT}');
  print('runT == String = ${strRunT == String}');
  print('refT == String = ${strRefT == String}');
  print('');
  print('bool');
  print('runtimeType = $boolRunT');
  print('reflectedType = $boolRefT');
  print('runT == refT = ${boolRunT == boolRefT}');
  print('runT == bool = ${boolRunT == bool}');
  print('refT == bool = ${boolRefT == bool}');
  print('');
  print('integer');
  print('runtimeType = $intRunT');
  print('reflectedType = $intRefT');
  print('runT == refT = ${intRunT == intRefT}');
  print('runT == int = ${intRunT == int}');
  print('refT == int = ${intRefT == int}');
  print('');
  print('map');
  print('runtimeType = $mapRunT');
  print('reflectedType = $mapRefT');
  print('runT == refT = ${mapRunT == mapRefT}');
  print('runT == Map = ${mapRunT == Map}');
  print('refT == Map = ${mapRefT == Map}');
  print('');
  print('list');
  print('runtimeType = $listRunT');
  print('reflectedType = $listRefT');
  print('runT == refT = ${listRunT == listRefT}');
  print('runT == List = ${listRunT == List}');
  print('refT == List = ${listRefT == List}');
  print('');
  print('custom');
  print('runtimeType = $cusRunT');
  print('reflectedType = $cusRefT');
  print('runT == refT = ${cusRunT == cusRefT}');
  print('runT == A = ${cusRunT == A}');
  print('refT == A = ${cusRefT == A}');
  print('');
}


//OUTPUT
string
runtimeType = String
reflectedType = String
runT == refT = false
runT == String = true
refT == String = false

bool
runtimeType = bool
reflectedType = bool
runT == refT = true
runT == bool = true
refT == bool = true

integer
runtimeType = int
reflectedType = int
runT == refT = false
runT == int = true
refT == int = false

map
runtimeType = _LinkedHashMap
reflectedType = _LinkedHashMap
runT == refT = true
runT == Map = false
refT == Map = false

list
runtimeType = List
reflectedType = List
runT == refT = true
runT == List = false
refT == List = false

custom
runtimeType = A
reflectedType = A
runT == refT = true
runT == A = true
refT == A = true

additionally is there anyway of comparing 2 Types and finding if they are equal? as the example above shows that the 2 seperate Types of int aren't equal using the regular == operator.

like image 958
Daniel Robinson Avatar asked Feb 18 '14 11:02

Daniel Robinson


2 Answers

You will get different results when a class overrides the runtimeType member. Basically an Object can lie on its type.

You can read more in the thread : example of wanting to override runtimeType?.

like image 141
Alexandre Ardhuin Avatar answered Nov 20 '22 09:11

Alexandre Ardhuin


An example of what Alexandre said is the String type. In dart:core the String class overrides runtimeType to always return the base class type String. However in the VM there are a number of different runtime subtypes for String. i.e single character strings, ascii strings, utf8 strings. The mirror api returns the real underlying subtype.

See Gilad's (the API's designer) answer to this SO question.

"is there anyway of comparing 2 Types and finding if they are equal?"

There are three new methods coming soon that allow you to compare types when using mirrors: TypeMirror.isSubtypeOf, TypeMirror.isAssignableTo, ClassMirror.isSubclassOf.

like image 4
Greg Lowe Avatar answered Nov 20 '22 10:11

Greg Lowe