I have a dynamic x
and I would like to assign x
to T s
if x is T
, and otherwise assign null
to s
. S
Just use the as keyword
final tweet = tweets[index] as Tweet;
A combination of both prior two posts, without the logging.
Fallback defaults to null when not provided.
T cast<T>(dynamic x, {T fallback}) => x is T ? x : fallback;
Figured out my answer had a huge problem, type check was incorrect. For example T is num
returns false even if T
is passed num
. I temporarily fixed this issue for now by explicitly checking equality of T
with the desired type like T == int && T == double
but this might not work for checking subclassed types like T == num
. Overall I edited my answer so it would work as is now. Although the answer is ongoing work and will be improved better when I find a solution for this type checking problem.
Here's my modified version that supports parsing num
(i.e. int
, double
) and DateTime
within the tryCast
:
var decimalNumber = tryCast<double>("42.42", fallback: 0);
var integerNumber = tryCast<int>("42", fallback: 0);
var currentTimestamp = tryCast<DateTime>(DateTime.now().toIso8601String(), fallback: DateTime.now());
var someType = tryCast<SomeType>(jsonString['someType'], fallback: null);
/// Casts `x` of [dynamic] type to [T] type. With fallback value `fallback` if casting failed
/// Supports tryParse from [String] to {[num],[DateTime], [Uri]}
/// Edited from [this ](https://stackoverflow.com/a/59714798/10830091) StackOverflow answer
T tryCast<T>(dynamic x, {T fallback}) {
// tryParse from [String] `x`
if (x is String) {
if (T == int || T == double) {
// tryParse to [num] (i.e. [int], [double])
return num.tryParse(x) as T ?? fallback;
} else if (T == DateTime) {
// tryParse to [DateTime]
return DateTime.tryParse(x) as T ?? fallback;
} else if (T == Uri) {
// tryParse to [Uri]
return Uri.tryParse(x) as T ?? fallback;
}
}
try {
return (x as T) ?? fallback;
} on CastError catch (e) {
print('CastError when trying to cast $x to $T! Exception catched: $e');
return fallback;
}
}
Inspired from Magnus's answer.
Dart 2 has generic functions which allows
T cast<T>(x) => x is T ? x : null;
dynamic x = something();
String s = cast<String>(x);
you can also use
var /* or final */ s = cast<String>(x);
and get String
inferred for s
I use the following utility function, which allows for an optional fallback value and error logging.
T tryCast<T>(dynamic x, {T fallback}){
try{
return (x as T);
}
on CastError catch(e){
print('CastError when trying to cast $x to $T!');
return fallback;
}
}
var x = something();
String s = tryCast(x, fallback: 'nothing');