In Dart, syntactically nice way to cast dynamic to given type or return null?

前端 未结 5 1719
囚心锁ツ
囚心锁ツ 2021-02-18 23:20

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

5条回答
  •  独厮守ぢ
    2021-02-19 00:08

    EDIT

    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:

    Usage

    var decimalNumber = tryCast("42.42", fallback: 0);
    var integerNumber = tryCast("42", fallback: 0);
    var currentTimestamp = tryCast(DateTime.now().toIso8601String(), fallback: DateTime.now());
    var someType = tryCast(jsonString['someType'], fallback: null);
    

    Solution

    /// 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(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.

提交回复
热议问题