unsafe_ variance
Details about the 'unsafe_variance' diagnostic produced by the Dart analyzer.
This type is unsafe: a type parameter occurs in a non-covariant position.
Description
#The analyzer produces this diagnostic when an instance member has a result type which is contravariant or invariant in a type parameter of the enclosing declaration. The result type of a variable is its type, and the result type of a getter or method is its return type. This lint warns against such members because they are likely to cause a failing type check at run time, with no static warning or error at the call site.
Example
#
The following code produces this diagnostic because
X occurs as a parameter type in the type of
f, which is a contravariant occurrence of this
type parameter:
class C<X> {
final bool Function(X) f;
C(this.f);
}
This is unsafe: If c has static type
C<num> and run-time type
C<int>
then c.f will throw. Hence, every invocation
c.f(a) will also throw, even in the case where
a has a correct type as an argument to
c.f.
Common fixes
#
If the linted member is or can be private then you may be able
to enforce that it is never accessed on any other receiver
than this. This is sufficient to ensure that that
the run-time type error does not occur. For example:
class C<X> {
// NB: Ensure manually that `_f` is only accessed on `this`.
// ignore: unsafe_variance
final 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);
}
You can eliminate the unsafe variance by using a more general type for the linted member. In this case you may need to check the run-time type and perform a downcast at call sites.
class C<X> {
final bool Function(Never) f;
C(this.f);
}
If c has static type
C<num> then you may test the type. For
example, c.f is bool Function(num). You may
safely call it with an argument of type num if it
has that type.
You can also eliminate the unsafe variance by using a much
more general type like Function, which is
essentially the type dynamic
for functions.
class C<X> {
final Function f;
C(this.f);
}
This will make c.f(a) dynamically safe: It will
throw if and only if the argument a does not have
the type required by the function. This is better than the
original version because it will not throw because of a
mismatched static type. It only throws when it
must throw for soundness reasons.
除非另有说明,文档之所提及适用于 Dart 3.12.2 版本报告页面问题.