avoid_ dynamic_ calls
Avoid method calls or property accesses on a dynamic
target.
Details
#
DO
avoid method calls or accessing properties on an object that is either
explicitly or implicitly statically typed
dynamic
. Dynamic calls are treated
slightly different in every runtime environment and compiler, but most
production modes (and even some development modes) have both compile size and
runtime performance penalties associated with dynamic calls.
Additionally, targets typed
dynamic
disables most static analysis, meaning it
is easier to lead to a runtime
NoSuchMethodError
or
TypeError
than properly
statically typed Dart code.
There is an exception to methods and properties that exist on Object?
:
a.hashCode
a.runtimeType
a.noSuchMethod(someInvocation)
a.toString()
... these members are dynamically dispatched in the web-based runtimes, but not
in the VM-based ones. Additionally, they are so common that it would be very
punishing to disallow
any.toString()
or
any == true
, for example.
Note that despite
Function
being a type, the semantics are close to identical
to
dynamic
, and calls to an object that is typed
Function
will also trigger
this lint.
Dynamic calls are allowed on cast expressions (as dynamic
or
as Function
).
BAD:
void explicitDynamicType(dynamic object) {
print(object.foo());
}
void implicitDynamicType(object) {
print(object.foo());
}
abstract class SomeWrapper {
T doSomething<T>();
}
void inferredDynamicType(SomeWrapper wrapper) {
var object = wrapper.doSomething();
print(object.foo());
}
void callDynamic(dynamic function) {
function();
}
void functionType(Function function) {
function();
}
GOOD:
void explicitType(Fooable object) {
object.foo();
}
void castedType(dynamic object) {
(object as Fooable).foo();
}
abstract class SomeWrapper {
T doSomething<T>();
}
void inferredType(SomeWrapper wrapper) {
var object = wrapper.doSomething<Fooable>();
object.foo();
}
void functionTypeWithParameters(Function() function) {
function();
}
Enable
#
To enable the
avoid_dynamic_calls
rule, add
avoid_dynamic_calls
under
linter > rules
in your
analysis_options.yaml
file:
linter:
rules:
- avoid_dynamic_calls
If you're instead using the YAML map syntax to configure linter rules,
add
avoid_dynamic_calls: true
under
linter > rules:
linter:
rules:
avoid_dynamic_calls: true
Unless stated otherwise, the documentation on this site reflects Dart 3.9.2. Report an issue.