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
不具有函数所需的类型时,它才会抛出异常。这比原始版本更好,因为它不会因为静态类型不匹配而抛出。它仅在出于健全性原因必须抛出时抛出。