Home > Enterprise >  How to cast an Object to Map (without using 'as')?
How to cast an Object to Map (without using 'as')?

Time:05-18

Variable 'valor' is of type 'Object'.

'valor' stores a 'Map<String, String>'.

I can 'convert' valor to a Map using:

var json = valor as Map<String, String>;

The question is: Can I do the same thing without using 'as' ?

CodePudding user response:

Sorry but you can't, even method such as Iterable.cast() are using the as keyword under the hood.

You can check the Dart type system documentation for confirmation.

CodePudding user response:

You can and should check if valor is a Map<String, String> first and allow it to be automatically type-promoted:

if (valor is Map<String, String>) {
  // `valor` is now known to be a `Map<String, String>`.
  var json = valor;
  ...
}

Note that type promotion can occur only for local variables, so if valor is not local, you must create a local reference first.

CodePudding user response:

You can cast without an explicit as, by going through dynamic.

dynamic dynamicValue = valor; // Valid up-cast.
Map<String, String> map = dynamicValue; // Implicit down-cast.

The implicit downcast is effectively an as Map<String, String> which is inserted by the compiler.

When compiling for the web, with "unsound optimizations" enabled, the implicit cast is optimized away and the compiler just blindly treats the value as a Map<String, String>, whether it is one or not.

If that's your goal, to avoid the cost of a cast at runtime, you can also just do:

Map<String, String> json = valor as dynamic;

That as is an up-cast, which is always sound and has no runtime overhead.

(Depending on your analyzer configuration, you may get warnings about implicit downcasts.)

Another approach, which doesn't use as, but does cost at runtime, is to use promotion:

Map<String, String> json;
if (valor is Map<String, String>) { // no `as`, but still a check.
  json = valor; 
} else {
  throw UnsupportedError("But it should be a map!");
}
// json is assigned here.

No use of as, but just as many type checks as as Map<String, String> does, so maybe not what you want anyway.

  •  Tags:  
  • dart
  • Related