跳到主要內容

avoid_dynamic_calls

穩定

避免在動態目標上進行方法呼叫或屬性存取。

詳細資訊

#

務必避免在明確或隱含地靜態類型為 dynamic 的物件上進行方法呼叫或存取屬性。動態呼叫在每個執行階段環境和編譯器中的處理方式略有不同,但大多數生產模式(甚至某些開發模式)都存在與動態呼叫相關的編譯大小和執行階段效能損失。

此外,類型為 dynamic 的目標會停用大多數靜態分析,這表示相較於正確的靜態類型 Dart 程式碼,它更容易導致執行階段 NoSuchMethodErrorTypeError

Object? 上存在的方法和屬性有一個例外

  • a.hashCode
  • a.runtimeType
  • a.noSuchMethod(someInvocation)
  • a.toString()

... 這些成員在基於網路的執行階段中是動態分派的,但在基於 VM 的執行階段中則不是。此外,它們非常常見,以至於禁止例如 any.toString()any == true 將會非常嚴厲。

請注意,儘管 Function 是一種類型,但語意與 dynamic 幾乎相同,並且呼叫類型為 Function 的物件也會觸發此 lint。

在轉型運算式(as dynamicas Function)上允許動態呼叫。

錯誤範例

dart
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();
}

正確範例

dart
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();
}

啟用

#

若要啟用 avoid_dynamic_calls 規則,請在您的 analysis_options.yaml 檔案中的 linter > rules 下新增 avoid_dynamic_calls

analysis_options.yaml
yaml
linter:
  rules:
    - avoid_dynamic_calls

如果您改用 YAML map 語法來設定 linter 規則,請在 linter > rules 下新增 avoid_dynamic_calls: true

analysis_options.yaml
yaml
linter:
  rules:
    avoid_dynamic_calls: true