Option A: not working
var a = <Widget?>[Container(), null];
a.removeNulls();
print(a.length == 1 && a[0] != null) // true
var b = a as List<Widget>; // _CastError (type 'List<Widget?>' is not a subtype of type 'List<Widget>' in type cast)
Option B: working
var a = <Widget?>[Container(), null];
a = a.whereType<Widget>().toList();
var b = a as List<Widget>; // works fine
.removeNull() is part of fast_immutable_collections
CodePudding user response:
I'm not familiar with the package, but quickly looking up the extension method shows that's just a wrapper over another function, removeWhere
, which has nothing to do with nullability.
Try print(a.runtimeType)
and you'll see List<Widget?>
. Thus, error thrown is correct.
As to why it is the case with the library, only the owner can answer that.
CodePudding user response:
A cast with as
treats as object as a different type. It does not mutate the object or create a new object.
Suppose that you could cast List<T?>
as List<T>
for a non-nullable type T
. For example:
var a = <int?>[0, 1, 2];
var b = a as List<int>; // Pretend that this is legal.
now b
and a
refer to the same List
object. But then consider:
a.add(null); // Legal. `a` is `List<int?>` and can accept `null`.
var last = b.last; // ???
Now you have a situation where b.last
would refer to a null
element even though b
claims to be a List
of non-nullable elements. Just because a
did not have null
elements at the time you casted it does not mean that it will not have null
elements in the future.
What you instead must do is to create a new List
object (e.g. with whereType<T>().toList()
) or must create a new List
-like object that performs runtime casts for each element (which is what List.cast
does).