How can I use Reflection (Mirrors) to access the m

2019-06-23 16:40发布

问题:

I need to "fetch" the methods in a Dart Class.

How can I do this?

And I want to be able to call the methods.

May I see an example?

回答1:

Here's an easy copy-pasteable code sample:

import 'dart:mirrors';
import 'dart:io';

main() {
  var im = reflect(new File('test')); // Retrieve the InstanceMirror of some class instance.
  im.type.methods.values.forEach((MethodMirror method) => print(method.simpleName));
}

Output is:

existsSync
_delete
exists
directory
_getDecodedLines
readAsTextSync
readAsBytesSync
readAsLinesSync
_directory
throwIfError
lastModifiedSync
readAsLines
open
_ensureFileService
deleteSync
delete
_exists
length
openInputStream
create
_create
readAsText
_openStdioSync
openOutputStream
_fullPath
_lastModified
fullPathSync
readAsBytes
lastModified
_openStdio
_open
openSync
lengthSync
directorySync
fullPath
createSync
_lengthFromName


回答2:

Here is a basic example:

(Note: You will want to have a (very) up to date version of the SDK for this, this was done in Dart Editor version 0.2.1_r14167, Dart SDK version 0.2.1.2_r14167 Nov 2, 2012)

My most sincere Thanks to Gilad of the Google Dart Team for providing this example!

#import('dart:mirrors');

class MyClass {
  String _test;

  String  get test       => _test;
  set     test(String paramVal)  => _test = paramVal;

  void my_method() {
  }

  void print_test(){
    print("test string is: ${_test}");
  }

  MyClass(String test) {
    _test = test;
  }

}


main() {

  MyClass myClass = new MyClass("Make my day, PUNK.");

  myClass.print_test();

  //ClassMirror myClassMirror = reflect(myClass).type;

  InstanceMirror myClassInstanceMirror = reflect(myClass);

  ClassMirror MyClassMirror = myClassInstanceMirror.type;

  Map<String, MethodMirror> map = MyClassMirror.methods;

  print("map = ${map}"); 

  map.values.forEach( (MethodMirror mm){
    myClassInstanceMirror.invoke(mm.simpleName,[]);
  });

}


回答3:

Concerning Reflection I have just written a couple of "Helper Functions" for fetching a LIST of the method names (not a Map) and invoking the method... all I can say for sure is that it works right now. There are likely technical reasons for not doing it this way - but in my case this does not run in a complex environment. However, I do think they nicely mask over a lot of details that not everybody is going to want to deal with.

Here's a functioning demonstration with and without the Helper functions:

#import('dart:mirrors');

class MyClass {
  String _test;
  String  get test               => _test;
  set     test(String paramVal)  => _test = paramVal;
  void my_method1(){print("in method1");}
  void my_method2(){print("in method2");}
  void print_test(){
    print("test string is: ${_test}");
  }
  MyClass(String test) {
    _test = test;
  }
}

//Helper Methods
InstanceMirror hMr;
List REFLECT_methods(Object myClass) {hMr=reflect(myClass);return(hMr.type.methods.values);}
REFLECT_invoke(MethodMirror mm){hMr.invoke(mm.simpleName, []);}

main() {

  MyClass myClass = new MyClass("Make my day, PUNK.");

  print("\n=======Using Raw Reflection================");
  InstanceMirror myClassInstanceMirror = reflect(myClass);
  ClassMirror MyClassMirror = myClassInstanceMirror.type;
  Map<String, MethodMirror> map1 = MyClassMirror.methods;
  map1.values.forEach( (MethodMirror mm){
    myClassInstanceMirror.invoke(mm.simpleName,[]);
  });

  print("\n==========Using Helper functions=============");
  List list2 = REFLECT_methods(myClass);
  list2.forEach((method){
    REFLECT_invoke(method);
  });  
}