Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

call a method if it exists

Is there a simple, lightweight/inexpensive call to determine if an object supports a named method? So, in this the obj.respondsTo would be great.

dynamic _toJson(dynamic obj) {
  return obj.respondsTo('toJson'))? obj.toJson() : obj;
}

class Foo {
  String foo = "Foo.foo";
  Bar bar = new Bar();
  Map toJson() {
    return {
      "foo" : _toJson(foo),
      "bar" : _toJson(bar)
    };
  }
}

One alternative would be just call it and catch a noSuchMethod exception, but I imagine that is bad practice and expensive?

like image 296
user1338952 Avatar asked Dec 04 '22 11:12

user1338952


2 Answers

The short answer is, 'no'. The answer provided by Frédéric Hamidi is not incorrect, but it does not work in dart2js (dart:mirrors is largely unimplemented in dart2js).

Also, while checking whether an object responds to a particular method is very common in other languages (Ruby, for example), it does not seem particularly Dart-y to me. Maybe once mirrors are fully supported in Dart, this will change.

And its hard to say whether reflection based on mirrors is 'lightweight/inexpensive'. It depends on the use case and how you define these terms.

I would say that your best bet is call the method on the object, catch the NoSuchMethod exception, and implement some default error-handling behavior. This especially makes sense if you normally expect the method to be present.

like image 113
Shailen Tuli Avatar answered May 21 '23 21:05

Shailen Tuli


You could define an interface/abstract class with an abstract method on test if the the object is of the interface type, and then call the method you now know exists.

abstract class JsonEncodable {
    Map toJSON();
}

Object _toJson(Object obj) {
    return (obj is JsonEncodable)? obj.toJson() : obj;
}

class Foo implements JsonEncodable {
    Map toJSON() {
        // toJSON implementation
    }
}
like image 41
thetrompf Avatar answered May 21 '23 22:05

thetrompf