unsafe_variance
此型別不安全:型別引數出現在了非協變位置。
描述
#當例項成員的結果型別在其包含宣告的型別引數中是逆變或不變時,分析器會生成此診斷。變數的結果型別即為其型別,getter 或方法的結果型別即為其返回型別。此 lint 會對此類成員發出警告,因為它們可能導致執行時型別檢查失敗,且在呼叫處沒有靜態警告或錯誤。
示例
#以下程式碼會生成此診斷,因為 X 作為引數型別出現在 f 的型別中,這是一種此型別引數的逆變出現。
dart
class C<X> {
bool Function(X) f;
C(this.f);
}這是不安全的:如果 c 具有靜態型別 C<num> 和執行時型別 C<int>,則 c.f 將會丟擲異常。因此,即使 a 作為 c.f 的引數具有正確的型別,每次呼叫 c.f(a) 也會丟擲異常。
常見修復方法
#如果受 lint 影響的成員是或可以是私有的,則您可以強制它僅在 this 以外的接收者上訪問。這足以確保不會發生執行時型別錯誤。例如
dart
class C<X> {
// NB: Ensure manually that `_f` is only accessed on `this`.
// ignore: unsafe_variance
bool Function(X) _f;
C(this._f);
// We can write a forwarding method to allow clients to call `_f`.
bool f(X x) => _f(x);
}透過為受 lint 影響的成員使用更通用的型別,可以消除不安全變異性。在這種情況下,您可能需要在呼叫處檢查執行時型別並執行向下轉型。
dart
class C<X> {
bool Function(Never) f;
C(this.f);
}如果 c 具有靜態型別 C<num>,則可以測試其型別。例如,c.f is bool Function(num)。如果它具有該型別,則可以安全地使用型別為 num 的引數呼叫它。
透過使用更通用的型別(例如 Function,它本質上是函式的 dynamic 型別),也可以消除不安全變異性。
dart
class C<X> {
Function f;
C(this.f);
}這將使 c.f(a) 動態安全:當且僅當引數 a 不具有函式所需的型別時,它才會丟擲異常。這比原始版本更好,因為它不會因為靜態型別不匹配而丟擲。它僅在出於健全性原因必須丟擲時丟擲。